/* Copyright (c) 2025 Beijing Semidrive Technology Corporation
 * SPDX-License-Identifier: Apache-2.0
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/** *****************************************************************************************************
 * \file     Mcu_Ckgen.c                                                                                *
 * \brief    AUTOSAR 4.3.1 MCAL Mcu Driver                                                              *
 *                                                                                                      *
 * <table>                                                                                              *
 * <tr><th>Date           <th>Version                                                                   *
 * <tr><td>2023/08/01     <td>1.0.0                                                                     *
 * </table>                                                                                             *
 *******************************************************************************************************/
/********************************************************************************************************
 *                                      Include header files                                            *
 *******************************************************************************************************/
#include "RegHelper.h"
#include "Mcu_Ckgen.h"
#include "Mcu_Fault.h"
#include "Mcu_Cfg.h"
#include "__regs_base.h"

/********************************************************************************************************
 *                                  Private Function Declarations                                       *
 *******************************************************************************************************/
#define MCU_START_SEC_CODE
#include "Mcu_MemMap.h"

static inline uint32 Mcu_Ip_CkgenXcgGetCtrlReg(uint32 base, uint32 id, uint32 type)
{
    return CKGEN_XCG_CTL_BASE(base, id, type);
}

/** *****************************************************************************************************
 * \brief bus slice divroot premux set, no need to switch mux
 *
 * \verbatim
 * Syntax             : static Std_ReturnType Mcu_Ip_CkgenBusSlicePreMuxNoChange(uint32 base, uint32 id, uint8 mux)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - CKGEN base address
 *                      id - bus slice id
 *                      mux - parent mux
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : errID
 *
 * Description        : bus slice divroot premux set, no need to switch mux
 *
 * \endverbatim
 * Traceability       : SW_SM005
 *******************************************************************************************************/
static Std_ReturnType Mcu_Ip_CkgenBusSlicePreMuxNoChange(uint32 base, uint32 id, uint8 mux)
{
    uint32 ctrlVal = readl(base + BUS_SLICE_CTL_OFF(id));
    Std_ReturnType errStatus = E_OK;
    uint32 mainEnStatus = (ctrlVal & BM_BUS_SLICE_CTL_MAIN_EN_STATUS);
    uint32 preMuxD0Active = (ctrlVal & BM_BUS_SLICE_CTL_PRE_MUX_D0_ACTIVE);
    uint32 preEnStatus = (ctrlVal & BM_BUS_SLICE_CTL_PRE_EN_STATUS);
    uint32 waitTimeoutFlag;

    McuFaultInj_Mcu_Ip_Mcu_Ip_CkgenBusSlicePreMuxNoChange_00();

    if ((mux == 4U) && (0U != mainEnStatus) && (0U == preMuxD0Active))
    {
        ctrlVal &= ~BM_BUS_SLICE_CTL_PRE_EN;
        writel(ctrlVal, (base + BUS_SLICE_CTL_OFF(id)));

        waitTimeoutFlag = Mcu_Ip_WaitForBitTimes((base + BUS_SLICE_CTL_OFF(id)), BM_BUS_SLICE_CTL_PRE_EN_STATUS,
                                            0U, CKGEN_WAIT_TIME);
        McuFaultInj_Mcu_Ip_Mcu_Ip_CkgenBusSlicePreMuxNoChange_01();
        if (FALSE == waitTimeoutFlag)
        {
            errStatus = MCU_E_TIMEOUT;
        } /* else not needed */
    }
    else if ((mux < 4U) && (0U != preEnStatus) && (0U != preMuxD0Active))
    {
        ctrlVal &= ~BM_BUS_SLICE_CTL_CLK_SRC_SEL_BIT3;
        writel(ctrlVal, (base + BUS_SLICE_CTL_OFF(id)));

        waitTimeoutFlag = Mcu_Ip_WaitForBitTimes((base + BUS_SLICE_CTL_OFF(id)), BM_BUS_SLICE_CTL_POST_MUX_D0_ACTIVE,
                                            1U, CKGEN_WAIT_TIME);
        McuFaultInj_Mcu_Ip_Mcu_Ip_CkgenBusSlicePreMuxNoChange_02();
        if (FALSE == waitTimeoutFlag)
        {
            errStatus = MCU_E_TIMEOUT;
        }
        else
        {
            ctrlVal = readl(base + BUS_SLICE_CTL_OFF(id));
            ctrlVal &= ~BM_BUS_SLICE_CTL_MAIN_EN;
            writel(ctrlVal, (base + BUS_SLICE_CTL_OFF(id)));
            waitTimeoutFlag = Mcu_Ip_WaitForBitTimes((base + BUS_SLICE_CTL_OFF(id)), BM_BUS_SLICE_CTL_MAIN_EN_STATUS,
                              0U, CKGEN_WAIT_TIME);
            McuFaultInj_Mcu_Ip_Mcu_Ip_CkgenBusSlicePreMuxNoChange_03();
            if (FALSE == waitTimeoutFlag)
            {
                errStatus = MCU_E_TIMEOUT;
            } /* else not needed */
        }
    }
    else
    {
        errStatus = MCU_E_PARAM_CONFIG;
    }

    return errStatus;
}

/** *****************************************************************************************************
 * \brief bus slice ratio set
 *
 * \verbatim
 * Syntax             : static void Mcu_Ip_CkgenSetRatio(uint32 base, Mcu_ClkBusRatioType ratio)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - CKGEN base address
 *                      ratio - 0:core/axi/apb 4/2/1, 1:core/axi/apb 2/2/1
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : errID
 *
 * Description        : bus slice ratio set
 *
 * \endverbatim
 * Traceability       : SW_SM005
 *******************************************************************************************************/
static void Mcu_Ip_CkgenSetRatio(uint32 base, Mcu_ClkBusRatioType ratio)
{
    uint32 value = readl(base + CKGEN_RES_OFF);

    value &= ~1U;
    value |= (uint32)ratio;
    writel(value, (base + CKGEN_RES_OFF));
}

/** *****************************************************************************************************
 * \brief Set the m/n/p/q div values at once, in order to satisfy the proportionality requirement
 *
 * \verbatim
 * Syntax             : static Std_ReturnType Mcu_Ip_CkgenBusSliceSetMnpqDivOnetime(uint32 base, uint32 id, uint8 divM,
        uint8 divN, uint8 divP, uint8 divQ)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - CKGEN base address
 *                      id - bus slice id
 *                      divM - divM
 *                      divN - divN
 *                      divP - divP
 *                      divQ - divQ
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : errID
 *
 * Description        : Set the m/n/p/q div values at once, in order to satisfy the proportionality requirement
 *                      taishan: ap domain n (ap bus):p (ap apb) must be 2:1 while setting up
 *                      taishanl/tainshanll: ap domain (ap bus:apb fixed to 2:1);
 *                                           p is for fusalib only. mcal does not need to configure p
 *
 * \endverbatim
 * Traceability       : SW_SM005
 *******************************************************************************************************/
static Std_ReturnType Mcu_Ip_CkgenBusSliceSetMnpqDivOnetime(uint32 base, uint32 id, uint8 divM,
        uint8 divN, uint8 divP, uint8 divQ)
{
    uint32 syncCtrlReg = base + BUS_SLICE_SYNC_CTL_OFF(id);
    uint32 divFlag = 0U;
    uint32 divMnpq = readl(syncCtrlReg) & 0xFFFFU;
    Std_ReturnType errStatus = E_OK;
    volatile uint32 timesOut = CKGEN_WAIT_TIME;

    if (divM > 0U)
    {
        divFlag = BM_BUS_SLICE_SYNC_CTL_DIV_M_CHG_BUSY;
        divMnpq &= ~FM_BUS_SLICE_SYNC_CTL_DIV_M_NUM;
        divMnpq |= FV_BUS_SLICE_SYNC_CTL_DIV_M_NUM((uint32)divM - 1U);
    }

    if (divN > 0U)
    {
        divFlag |= BM_BUS_SLICE_SYNC_CTL_DIV_N_CHG_BUSY;
        divMnpq &= ~FM_BUS_SLICE_SYNC_CTL_DIV_N_NUM;
        divMnpq |= FV_BUS_SLICE_SYNC_CTL_DIV_N_NUM((uint32)divN - 1U);
    }

    if (divP > 0U)
    {
        divFlag |= BM_BUS_SLICE_SYNC_CTL_DIV_P_CHG_BUSY;
        divMnpq &= ~FM_BUS_SLICE_SYNC_CTL_DIV_P_NUM;
        divMnpq |= FV_BUS_SLICE_SYNC_CTL_DIV_P_NUM((uint32)divP - 1U);
    }

    if (divQ > 0U)
    {
        divFlag |= BM_BUS_SLICE_SYNC_CTL_DIV_Q_CHG_BUSY;
        divMnpq &= ~FM_BUS_SLICE_SYNC_CTL_DIV_Q_NUM;
        divMnpq |= FV_BUS_SLICE_SYNC_CTL_DIV_Q_NUM((uint32)divQ - 1U);
    }

    if (0U != divFlag)
    {
        writel(divMnpq, syncCtrlReg);

        while ((timesOut != 0U) && (0U != (readl(syncCtrlReg) & divFlag)))
        {
            /* PRQA S 3387 1 */
            timesOut--;
        }

        if (timesOut == 0U)
        {
            errStatus = MCU_E_TIMEOUT;
        }/* else not needed */
    }

    return errStatus;
}
/** *****************************************************************************************************
 * \brief bus slice divroot premux set, switch to clkin4
 *
 * \verbatim
 * Syntax             : static Std_ReturnType Mcu_Ip_CkgenBusSlicePreMuxClkIn4(uint32 base, uint32 id)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - CKGEN base address
 *                      id - bus slice id
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : errID
 *
 * Description        : bus slice divroot premux set, switch to clkin4
 *
 * \endverbatim
 * Traceability       : SW_SM005
 *******************************************************************************************************/
static Std_ReturnType Mcu_Ip_CkgenBusSlicePreMuxClkIn4(uint32 base, uint32 id)
{
    Std_ReturnType errStatus = E_OK;
    uint32 value = readl(base + BUS_SLICE_CTL_OFF(id));
    boolean timeoutFlag;

    /* Make sure CG is enabled. */
    value |= BM_BUS_SLICE_CTL_MAIN_EN;
    writel(value, (base + BUS_SLICE_CTL_OFF(id)));

    timeoutFlag = Mcu_Ip_WaitForBitTimes((base + BUS_SLICE_CTL_OFF(id)), BM_BUS_SLICE_CTL_MAIN_EN_STATUS,
                                         1U, CKGEN_WAIT_TIME);

    if (FALSE == timeoutFlag)
    {
        errStatus = MCU_E_TIMEOUT;
    }
    else
    {
        /* set clk_src_sel[2] to 1b1. */
        value = readl(base + BUS_SLICE_CTL_OFF(id));
        value |= BM_BUS_SLICE_CTL_CLK_SRC_SEL_CLKIN4;
        writel(value, (base + BUS_SLICE_CTL_OFF(id)));

        timeoutFlag = Mcu_Ip_WaitForBitTimes((base + BUS_SLICE_CTL_OFF(id)), BM_BUS_SLICE_CTL_PRE_MUX_D0_ACTIVE,
                                             0U, CKGEN_WAIT_TIME);

        if (FALSE == timeoutFlag)
        {
            errStatus = MCU_E_TIMEOUT;
        }
        else
        {
            value = readl(base + BUS_SLICE_CTL_OFF(id));
            value &= ~BM_BUS_SLICE_CTL_PRE_EN;
            writel(value, (base + BUS_SLICE_CTL_OFF(id)));

            timeoutFlag = Mcu_Ip_WaitForBitTimes((base + BUS_SLICE_CTL_OFF(id)), BM_BUS_SLICE_CTL_PRE_EN_STATUS,
                                                 0U, CKGEN_WAIT_TIME);

            if (FALSE == timeoutFlag)
            {
                errStatus = MCU_E_TIMEOUT;
            } /* else not needed */
        }
    }

    return errStatus;
}
/** *****************************************************************************************************
 * \brief bus slice divroot premux set, switch to clkin1~3
 *
 * \verbatim
 * Syntax             : static Std_ReturnType Mcu_Ip_CkgenBusSlicePreMuxNotClkIn4(uint32 base, uint32 id, uint8 mux)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - CKGEN base address
 *                      id - bus slice id
 *                      mux - parent mux
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : errID
 *
 * Description        : bus slice divroot premux set, switch to clkin1~3
 *
 * \endverbatim
 * Traceability       : SW_SM005
 *******************************************************************************************************/
static Std_ReturnType Mcu_Ip_CkgenBusSlicePreMuxNotClkIn4(uint32 base, uint32 id, uint8 mux)
{
    Std_ReturnType errStatus = E_OK;
    uint32 value = (readl(base + BUS_SLICE_CTL_OFF(id)) & BM_BUS_SLICE_CTL_PRE_EN_STATUS);
    boolean timeoutFlag;

    if (0U != value)
    {
        /*set reg_pre_en to 1b0, wait pre_en_ack to 1b0.*/
        value = readl(base + BUS_SLICE_CTL_OFF(id));
        value &= ~BM_BUS_SLICE_CTL_PRE_EN;
        writel(value, (base + BUS_SLICE_CTL_OFF(id)));

        timeoutFlag = Mcu_Ip_WaitForBitTimes((base + BUS_SLICE_CTL_OFF(id)), BM_BUS_SLICE_CTL_PRE_EN_STATUS,
                                            0U, CKGEN_WAIT_TIME);
        if (FALSE == timeoutFlag)
        {
            errStatus = MCU_E_TIMEOUT;
        }
    }

    if (E_OK == errStatus)
    {
        /* set clk_src_sel[1:0] to select the clock.*/
        value = readl(base + BUS_SLICE_CTL_OFF(id));
        value &= ~3U;
        value |= FV_BUS_SLICE_CTL_CLK_SRC_SEL(mux);
        writel(value, (base + BUS_SLICE_CTL_OFF(id)));

        /*set reg_pre_en to 1b1, wait pre_en_ack to 1b1.*/
        value = readl(base + BUS_SLICE_CTL_OFF(id));
        value |= BM_BUS_SLICE_CTL_PRE_EN;
        writel(value, (base + BUS_SLICE_CTL_OFF(id)));

        timeoutFlag = Mcu_Ip_WaitForBitTimes((base + BUS_SLICE_CTL_OFF(id)), BM_BUS_SLICE_CTL_PRE_EN_STATUS,
                                            1U, CKGEN_WAIT_TIME);
        if (FALSE == timeoutFlag)
        {
            errStatus = MCU_E_TIMEOUT;
        }
        else
        {
            /* set clk_src_sel[2] to 1b0. */
            value = readl(base + BUS_SLICE_CTL_OFF(id));
            value &= ~BM_BUS_SLICE_CTL_CLK_SRC_SEL_CLKIN4;
            writel(value, (base + BUS_SLICE_CTL_OFF(id)));

            timeoutFlag = Mcu_Ip_WaitForBitTimes((base + BUS_SLICE_CTL_OFF(id)), BM_BUS_SLICE_CTL_PRE_MUX_D0_ACTIVE,
                                                1U, CKGEN_WAIT_TIME);
            if (FALSE == timeoutFlag)
            {
                errStatus = MCU_E_TIMEOUT;
            }
            else
            {
                value = readl(base + BUS_SLICE_CTL_OFF(id));
                value &= ~BM_BUS_SLICE_CTL_MAIN_EN;
                writel(value, (base + BUS_SLICE_CTL_OFF(id)));

                timeoutFlag = Mcu_Ip_WaitForBitTimes((base + BUS_SLICE_CTL_OFF(id)), BM_BUS_SLICE_CTL_MAIN_EN_STATUS,
                                                    0U, CKGEN_WAIT_TIME);
                if (FALSE == timeoutFlag)
                {
                    errStatus = MCU_E_TIMEOUT;
                }/* else not needed */
            }
        }
    }/* else not needed */

    return errStatus;
}

/** *****************************************************************************************************
 * \brief bus slice divroot premux set
 *
 * \verbatim
 * Syntax             : static Std_ReturnType Mcu_Ip_CkgenBusSliceSetPreMux(uint32 base, uint32 id, uint8 mux)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - CKGEN base address
 *                      id - bus slice id
 *                      mux - parent mux
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : errID
 *
 * Description        : bus slice divroot premux set
 *
 * \endverbatim
 * Traceability       : SW_SM005
 *******************************************************************************************************/
static Std_ReturnType Mcu_Ip_CkgenBusSliceSetPreMux(uint32 base, uint32 id, uint8 mux)
{
    uint32 ctrlVal = readl(base + BUS_SLICE_CTL_OFF(id));
    uint8 oldMux;
    Std_ReturnType errStatus = E_OK;
    uint32 value;

    oldMux = Mcu_Ip_CkgenBusGetPreMux(base, id);

    /*if mux == oldmux, no need to reconfig*/
    if (mux == oldMux)
    {
        errStatus = Mcu_Ip_CkgenBusSlicePreMuxNoChange(base, id, mux);
    }
    else
    {
        /* sel ck_in4 first */
        value = (ctrlVal & BM_BUS_SLICE_CTL_PRE_MUX_D0_ACTIVE);

        if (0U != value)
        {
            errStatus = Mcu_Ip_CkgenBusSlicePreMuxClkIn4(base, id);
        } /* else not needed */

        /* sel ck_in0 to ck_in3 */
        if ((mux < 4U) && (E_OK == errStatus))
        {
            errStatus = Mcu_Ip_CkgenBusSlicePreMuxNotClkIn4(base, id, mux);
        } /* else not needed */
    }

    return errStatus;
}

/** *****************************************************************************************************
 * \brief Set the m/n/p/q div values
 *
 * \verbatim
 * Syntax             : static Std_ReturnType Mcu_Ip_CkgenBusDivMnpqSetRate(uint32 base, uint32 id, uint32 type, uint32 divNum)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - CKGEN base address
 *                      id - bus slice id
 *                      type - mnpq type
 *                      divNum - mnpq div value
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : errID
 *
 * Description        : Set the m/n/p/q div values
 *                      taishan: ap domain n (ap bus):p (ap apb) must be 2:1 while setting up
 *                      taishanl/tainshanll: ap domain (ap bus:apb fixed to 2:1);
 *                                           p is for fusalib only. mcal does not need to configure p
 *
 * \endverbatim
 * Traceability       : SW_SM005
 *******************************************************************************************************/
static Std_ReturnType Mcu_Ip_CkgenBusDivMnpqSetRate(uint32 base, uint32 id, uint32 type,
        uint32 divNum)
{
    uint32 syncCtrlReg = base + BUS_SLICE_SYNC_CTL_OFF(id);
    uint32 value = readl(syncCtrlReg);
    Std_ReturnType errStatus = E_OK;

    McuFaultInj_Mcu_Ip_CkgenBusDivMnpqSetRate_01();

    switch (type)
    {
    case CKGEN_BUS_ID_TYPE_DIV_M:
        value &= ~FM_BUS_SLICE_SYNC_CTL_DIV_M_NUM;
        value |= FV_BUS_SLICE_SYNC_CTL_DIV_M_NUM(divNum - 1U);
        writel(value, syncCtrlReg);
        if (FALSE == Mcu_Ip_WaitForBitTimes(syncCtrlReg, BM_BUS_SLICE_SYNC_CTL_DIV_M_CHG_BUSY,
                                        0U, CKGEN_WAIT_TIME))
        {
            errStatus = MCU_E_TIMEOUT;
        } /* else not needed */
        break;
    case CKGEN_BUS_ID_TYPE_DIV_N:
        value &= ~FM_BUS_SLICE_SYNC_CTL_DIV_N_NUM;
        value |= FV_BUS_SLICE_SYNC_CTL_DIV_N_NUM(divNum - 1U);
        writel(value, syncCtrlReg);
        if (FALSE == Mcu_Ip_WaitForBitTimes(syncCtrlReg, BM_BUS_SLICE_SYNC_CTL_DIV_N_CHG_BUSY,
                                        0U, CKGEN_WAIT_TIME))
        {
            errStatus = MCU_E_TIMEOUT;
        } /* else not needed */
        break;
    case CKGEN_BUS_ID_TYPE_DIV_P:
        value &= ~FM_BUS_SLICE_SYNC_CTL_DIV_P_NUM;
        value |= FV_BUS_SLICE_SYNC_CTL_DIV_P_NUM(divNum - 1U);
        writel(value, syncCtrlReg);
        if (FALSE == Mcu_Ip_WaitForBitTimes(syncCtrlReg, BM_BUS_SLICE_SYNC_CTL_DIV_P_CHG_BUSY,
                                        0U, CKGEN_WAIT_TIME))
        {
            errStatus = MCU_E_TIMEOUT;
        } /* else not needed */
        break;
    case CKGEN_BUS_ID_TYPE_DIV_Q:
        value &= ~FM_BUS_SLICE_SYNC_CTL_DIV_Q_NUM;
        value |= FV_BUS_SLICE_SYNC_CTL_DIV_Q_NUM(divNum - 1U);
        writel(value, syncCtrlReg);
        if (FALSE == Mcu_Ip_WaitForBitTimes(syncCtrlReg, BM_BUS_SLICE_SYNC_CTL_DIV_Q_CHG_BUSY,
                                        0U, CKGEN_WAIT_TIME))
        {
            errStatus = MCU_E_TIMEOUT;
        } /* else not needed */
        break;
    default:
        errStatus = MCU_E_PARAM_CONFIG;
        break;
    }

    return errStatus;
}

/** *****************************************************************************************************
 * \brief ip slice rate mux set, no need to switch mux
 *
 * \verbatim
 * Syntax             : static Std_ReturnType Mcu_Ip_CkgenIpSliceMuxNoChange(uint32 base, uint32 id, uint8 mux)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - CKGEN base address
 *                      id - ip slice id
 *                      mux - parent mux
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : errID
 *
 * Description        : ip slice rate mux set, no need to switch mux
 *
 * \endverbatim
 * Traceability       : SW_SM005
 *******************************************************************************************************/
static Std_ReturnType Mcu_Ip_CkgenIpSliceMuxNoChange(uint32 base, uint32 id, uint8 mux)
{
    uint32 ctrlReg = base + IP_SLICE_CTL_OFF(id);
    uint32 ctrlVal = readl(ctrlReg);
    Std_ReturnType errStatus = E_OK;
    uint32 mainEnStatus = (ctrlVal & BM_IP_SLICE_CTL_MAIN_EN_STATUS);
    uint32 preEnStatus = (ctrlVal & BM_IP_SLICE_CTL_PRE_EN_STATUS);
    uint32 d0Active = (ctrlVal & BM_IP_SLICE_CTL_MUX_D0_ACTIVE);


    if ((4U == mux) && (0U != mainEnStatus) && (0U == d0Active))
    {

        ctrlVal &= ~BM_IP_SLICE_CTL_PRE_EN;
        writel(ctrlVal, ctrlReg);

        if (FALSE == Mcu_Ip_WaitForBitTimes(ctrlReg, BM_IP_SLICE_CTL_PRE_EN_STATUS,
                                            0U, CKGEN_WAIT_TIME))
        {
            errStatus = MCU_E_TIMEOUT;
        } /* else not needed */
    }
    else
    {
        if ((mux < 4U) && (0U != preEnStatus) && (0U != d0Active))
        {
            ctrlVal &= ~BM_IP_SLICE_CTL_MAIN_EN;
            writel(ctrlVal, ctrlReg);

            if (FALSE == Mcu_Ip_WaitForBitTimes(ctrlReg, BM_IP_SLICE_CTL_MAIN_EN_STATUS,
                                                0U, CKGEN_WAIT_TIME))
            {
                errStatus = MCU_E_TIMEOUT;
            } /* else not needed */
        }
        else
        {
            errStatus = MCU_E_PARAM_CONFIG;
        }
    }

    return errStatus;
}

/** *****************************************************************************************************
 * \brief ip slice mux set, switch to clkin4
 *
 * \verbatim
 * Syntax             : static Std_ReturnType Mcu_Ip_CkgenIpSliceMuxClkIn4(uint32 base, uint32 id)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - CKGEN base address
 *                      id - ip slice id
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : errID
 *
 * Description        : ip slice mux set, switch to clkin4
 *
 * \endverbatim
 * Traceability       : SW_SM005
 *******************************************************************************************************/
static Std_ReturnType Mcu_Ip_CkgenIpSliceMuxClkIn4(uint32 base, uint32 id)
{
    uint32 ctrlReg = base + IP_SLICE_CTL_OFF(id);
    uint32 value = readl(ctrlReg);
    Std_ReturnType errStatus = E_OK;
    boolean timeoutFlag;

    /* Make sure CG is enabled. */
    value |= BM_IP_SLICE_CTL_MAIN_EN;
    writel(value, ctrlReg);

    timeoutFlag = Mcu_Ip_WaitForBitTimes(ctrlReg, BM_IP_SLICE_CTL_MAIN_EN_STATUS,
                                        1U, CKGEN_WAIT_TIME);
    if (FALSE == timeoutFlag)
    {
        errStatus = MCU_E_TIMEOUT;
    }
    else
    {
        /* set clk_src_sel[2] to 1b1. */
        value = readl(ctrlReg);
        value |= BM_IP_SLICE_CTL_CLK_SRC_SEL_CLKIN4;
        writel(value, ctrlReg);

        timeoutFlag = Mcu_Ip_WaitForBitTimes(ctrlReg, BM_IP_SLICE_CTL_MUX_D0_ACTIVE,
                                            0U, CKGEN_WAIT_TIME);
        if (FALSE == timeoutFlag)
        {
            errStatus = MCU_E_TIMEOUT;
        }
        else
        {
            value = readl(ctrlReg);
            value &= ~BM_IP_SLICE_CTL_PRE_EN;
            writel(value, ctrlReg);

            timeoutFlag = Mcu_Ip_WaitForBitTimes(ctrlReg, BM_IP_SLICE_CTL_PRE_EN_STATUS,
                                                0U, CKGEN_WAIT_TIME);
            if (FALSE == timeoutFlag)
            {
                errStatus = MCU_E_TIMEOUT;
            }/* else not needed*/
        }
    }

    return errStatus;
}

/** *****************************************************************************************************
 * \brief ip slice mux set, switch to clkin1~3
 *
 * \verbatim
 * Syntax             : static Std_ReturnType Mcu_Ip_CkgenIpSliceMuxNotClkIn4(uint32 base, uint32 id, uint8 mux)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - CKGEN base address
 *                      id - ip slice id
 *                      mux - parent mux
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : errID
 *
 * Description        : ip slice mux set, switch to clkin1~3
 *
 * \endverbatim
 * Traceability       : SW_SM005
 *******************************************************************************************************/
static Std_ReturnType Mcu_Ip_CkgenIpSliceMuxNotClkIn4(uint32 base, uint32 id, uint8 mux)
{
    uint32 ctrlReg = base + IP_SLICE_CTL_OFF(id);
    Std_ReturnType errStatus = E_OK;
    uint32 value = (readl(ctrlReg) & BM_IP_SLICE_CTL_PRE_EN_STATUS);
    boolean timeoutFlag;

    McuFaultInj_Mcu_Ip_CkgenIpSliceMuxNotClkIn4_01();

    if (0U != value)
    {
        /*set reg_pre_en to 1b0, wait pre_en_ack to 1b0.*/
        value = readl(ctrlReg);
        value &= ~BM_IP_SLICE_CTL_PRE_EN;
        writel(value, ctrlReg);

        timeoutFlag = Mcu_Ip_WaitForBitTimes(ctrlReg, BM_IP_SLICE_CTL_PRE_EN_STATUS,
                                            0U, CKGEN_WAIT_TIME);
        McuFaultInj_Mcu_Ip_CkgenIpSliceMuxNotClkIn4_02();
        if (FALSE == timeoutFlag)
        {
            errStatus = MCU_E_TIMEOUT;
        }
    }

    if (E_OK == errStatus)
    {
        /* set clk_src_sel[1:0] to select the clock.*/
        value = readl(ctrlReg);
        value &= ~3U;
        value |= FV_IP_SLICE_CTL_CLK_SRC_SEL(mux);
        writel(value, ctrlReg);

        /*set reg_pre_en to 1b1, wait pre_en_ack to 1b1.*/
        value = readl(ctrlReg);
        value |= BM_IP_SLICE_CTL_PRE_EN;
        writel(value, ctrlReg);

        timeoutFlag = Mcu_Ip_WaitForBitTimes(ctrlReg, BM_IP_SLICE_CTL_PRE_EN_STATUS,
                                            1U, CKGEN_WAIT_TIME);
        McuFaultInj_Mcu_Ip_CkgenIpSliceMuxNotClkIn4_03();
        if (FALSE == timeoutFlag)
        {
            errStatus = MCU_E_TIMEOUT;
        }
        else
        {

            /* set clk_src_sel[2] to 1b0. */
            value = readl(ctrlReg);
            value &= ~BM_IP_SLICE_CTL_CLK_SRC_SEL_CLKIN4;
            writel(value, ctrlReg);

            timeoutFlag = Mcu_Ip_WaitForBitTimes(ctrlReg, BM_IP_SLICE_CTL_MUX_D0_ACTIVE,
                                                1U, CKGEN_WAIT_TIME);
            if (FALSE == timeoutFlag)
            {
                errStatus = MCU_E_TIMEOUT;
            }
            else
            {
                value = readl(ctrlReg);
                value &= ~BM_IP_SLICE_CTL_MAIN_EN;
                writel(value, ctrlReg);

                timeoutFlag = Mcu_Ip_WaitForBitTimes(ctrlReg, BM_IP_SLICE_CTL_MAIN_EN_STATUS,
                                                    0U, CKGEN_WAIT_TIME);
                if (FALSE == timeoutFlag)
                {
                    errStatus = MCU_E_TIMEOUT;
                }/* else not needed */
            }
        }
    }/* else not needed */

    return errStatus;
}

/** *****************************************************************************************************
 * \brief ip slice mux set
 *
 * \verbatim
 * Syntax             : static Std_ReturnType Mcu_Ip_CkgenIpSetMux(uint32 base, uint32 id, uint8 mux)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - CKGEN base address
 *                      id - ip slice id
 *                      mux - parent mux
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : errID
 *
 * Description        : ip slice mux set
 *
 * \endverbatim
 * Traceability       : SW_SM005
 *******************************************************************************************************/
static Std_ReturnType Mcu_Ip_CkgenIpSetMux(uint32 base, uint32 id, uint8 mux)
{
    uint32 ctrlReg = base + IP_SLICE_CTL_OFF(id);
    uint32 ctrlVal = readl(ctrlReg);
    uint8 oldMux;
    Std_ReturnType errStatus = E_OK;
    uint32 value;

    oldMux = Mcu_Ip_CkgenIpGetMux(base, id);

    if (oldMux == mux)
    {
        errStatus = Mcu_Ip_CkgenIpSliceMuxNoChange(base, id, mux);
    }
    else
    {
        /* sel ck_in4 first */
        value = (ctrlVal & BM_IP_SLICE_CTL_MUX_D0_ACTIVE);

        if (0U != value)
        {
            errStatus = Mcu_Ip_CkgenIpSliceMuxClkIn4(base, id);
        }

        McuFaultInj_Mcu_Ip_CkgenIpSetMux_01();
        if (E_OK == errStatus)
        {
            /* sel ck_in0 to ck_in3 */
            if (mux < 4U)
            {
                errStatus = Mcu_Ip_CkgenIpSliceMuxNotClkIn4(base, id, mux);
            } /* else not needed */
        } /* else not needed */
    }

    return errStatus;
}

/** *****************************************************************************************************
 * \brief ip slice div set
 *
 * \verbatim
 * Syntax             : static Std_ReturnType Mcu_Ip_CkgenIpSetDiv(uint32 base, uint32 id, uint32 divNum)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - CKGEN base address
 *                      id - ip slice id
 *                      divNum - divNum
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : errID
 *
 * Description        : ip slice div set
 *
 * \endverbatim
 * Traceability       : SW_SM005
 *******************************************************************************************************/
static Std_ReturnType Mcu_Ip_CkgenIpSetDiv(uint32 base, uint32 id, uint32 divNum)
{
    uint32 ctrlReg = base + IP_SLICE_CTL_OFF(id);
    uint32 value = readl(ctrlReg);
    Std_ReturnType errStatus = E_OK;

    value &=~FM_IP_SLICE_CTL_DIV_NUM;
    value |= FV_IP_SLICE_CTL_DIV_NUM(divNum - 1U);
    writel(value, ctrlReg);

    if (FALSE == Mcu_Ip_WaitForBitTimes(ctrlReg, BM_IP_SLICE_CTL_DIV_CHG_BUSY,
                                        0U, CKGEN_WAIT_TIME))
    {
        errStatus = MCU_E_TIMEOUT;
    } /* else not needed */

    return errStatus;
}

/** *****************************************************************************************************
 * \brief Calculate the actual frequency based on the record number.
 *
 * \verbatim
 * Syntax             : static Mcu_CkgenRateType Mcu_Ip_CkgenMonCalcFreq(uint32 base, uint16 freqMon, uint8 divAorB)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - CKGEN base address
 *                      freqMon - clock gate id
 *                      divAorB - clk_24m_div can be selected from clk_24m_mona or clk_24m_monb by software
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : Calculate the actual frequency
 *
 * Description        : Calculate the actual frequency based on the record number.
 *
 * \endverbatim
 * Traceability       : SW_SM006
 *******************************************************************************************************/
static Mcu_CkgenRateType Mcu_Ip_CkgenMonCalcFreq(uint32 base, uint16 freqMon, uint8 divAorB)
{
    uint32 glbCtrlVal;
    uint32 divAorBNum;
    Mcu_CkgenRateType rate;

    glbCtrlVal = readl(base + CKGEN_GLB_CTL1_OFF);

    if (1U == divAorB)
    {
        /* 24M divb */
        divAorBNum = GFV_CKGEN_GLB_CTL1_CLK_24M_DIV_B_NUM(glbCtrlVal);
    }
    else
    {
        /* 24M diva */
        divAorBNum = GFV_CKGEN_GLB_CTL1_CLK_24M_DIV_A_NUM(glbCtrlVal);
    }

    rate = (CKGEN_24M_RATE / 2U) / (divAorBNum + 1U);
    rate = rate * freqMon;

    return rate;
}

/** *****************************************************************************************************
 * \brief monitor div config.
 *
 * \verbatim
 * Syntax             : static void Mcu_Ip_CkgenSetMonDivNum(uint32 base, uint8 divType, uint32 divNum)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - CKGEN base address
 *                      divType - CKGEN_MON_DIVA/CKGEN_MON_DIVB
 *                      divNum - divNum
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : None
 *
 * Description        : monitor div config.
 *                      clock monitor freq is 24M/(clk_24m_div_x_num+1)/2
 *                      when monitored frequency is 600M~10M, use div_num_a(config to 0x3FF)
 *                      when monitored frequency is 10M~100K, use div_num_b(config to 0x27FF)
 *                      to get high ppm
 *
 * \endverbatim
 * Traceability       : SW_SM006
 *******************************************************************************************************/
static void Mcu_Ip_CkgenSetMonDivNum(uint32 base, uint8 divType, uint32 divNum)
{
    uint32 glbCtrl = base + CKGEN_GLB_CTL1_OFF;
    uint32 value =  readl(glbCtrl);

    McuFaultInj_Mcu_Ip_CkgenSetMonDivNum_01();

    if (CKGEN_MON_DIVA == divType)
    {
        if (GFV_CKGEN_GLB_CTL1_CLK_24M_DIV_A_NUM(value) != divNum)
        {
            value &= ~FM_CKGEN_GLB_CTL1_CLK_24M_DIV_A_NUM;
            value |= FV_CKGEN_GLB_CTL1_CLK_24M_DIV_A_NUM(divNum);
            writel(value, glbCtrl);
        } /* else not needed */
    }
    else if (CKGEN_MON_DIVB == divType)
    {
        if (GFV_CKGEN_GLB_CTL1_CLK_24M_DIV_B_NUM(value) != divNum)
        {
            value &= ~FM_CKGEN_GLB_CTL1_CLK_24M_DIV_B_NUM;
            value |= FV_CKGEN_GLB_CTL1_CLK_24M_DIV_B_NUM(divNum);
            writel(value, glbCtrl);
        } /* else not needed */
    }
    else
    {
        ; /* nothing to do*/
    }

}

/** *****************************************************************************************************
 * \brief select using mon_a or mon_b
 *
 * \verbatim
 * Syntax             : static void Mcu_Ip_CkgenSelectMonAorB(uint32 base, Mcu_CkgenType sliceType, uint32 typeIndex, uint32 rate)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - CKGEN base address
 *                      sliceType - sliceType
 *                      typeIndex - typeIndex
 *                      rate - expected rate
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : monSrcSel - 1: select mon_b, 0: select mon_a, 0xff- errors
 *
 * Description        : select using mon_a or mon_b
 *                      when monitored frequency is 600M~10M, use div_num_a(config to 0x3FF)
 *                      when monitored frequency is 10M~100K, use div_num_b(config to 0x27FF)
 * \endverbatim
 *******************************************************************************************************/
static uint8 Mcu_Ip_CkgenSelectMonAorB(uint32 base, Mcu_CkgenType sliceType, uint32 typeIndex,
                                       uint32 rate)
{
    uint32 ui32MonCtrlReg;
    uint8 monSrcSel = 0xFFU;

    if (CKGEN_IP_SLICE_TYPE == sliceType)
    {
        ui32MonCtrlReg =  readl(base + IP_SLICE_MON_CTL_OFF(typeIndex));

        /* when monitored frequency is 600M~10M, use div_num_a(config to 0x3FF)
        when monitored frequency is 10M~100K, use div_num_b(config to 0x27FF)*/
        if ((rate >= 100000U) && (rate < 10000000U))
        {
            ui32MonCtrlReg |= BM_IP_SLICE_MON_CTL_MON_CLK_SRC_SEL;
            monSrcSel = 1U;
        }
        else
        {
            ui32MonCtrlReg &= ~BM_IP_SLICE_MON_CTL_MON_CLK_SRC_SEL;
            monSrcSel = 0U;
        }

        writel(ui32MonCtrlReg, (base + IP_SLICE_MON_CTL_OFF(typeIndex)));
    }
    else if ((CKGEN_BUS_SLICE_TYPE == sliceType) || (CKGEN_SF_BUS_SLICE_TYPE == sliceType))
    {
        ui32MonCtrlReg =  readl(base + BUS_SLICE_MON_CTL_0_OFF(typeIndex));

        /* when monitored frequency is 600M~10M, use div_num_a(config to 0x3FF)
        when monitored frequency is 10M~100K, use div_num_b(config to 0x27FF)*/
        if ((rate >= 100000U) && (rate < 10000000U))
        {
            ui32MonCtrlReg |= BM_BUS_SLICE_MON_CTL_0_MON_CLK_SRC_SEL;
            monSrcSel = 1U;
        }
        else
        {
            ui32MonCtrlReg &= ~BM_BUS_SLICE_MON_CTL_0_MON_CLK_SRC_SEL;
            monSrcSel = 0U;
        }

        writel(ui32MonCtrlReg, (base + BUS_SLICE_MON_CTL_0_OFF(typeIndex)));
    }
    else
    {
        ; /* do nothing */
    }

    return monSrcSel;
}

/** *****************************************************************************************************
 * \brief select using mon_a or mon_b for dbg monitor
 *
 * \verbatim
 * Syntax             : static uint8 Mcu_Ip_CkgenDbgMonSelectAorB(uint32 base, uint32 rate)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - CKGEN base address
 *                      rate - expected rate
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : monSrcSel - 1: select mon_b, 0: select mon_a, 0xff- errors
 *
 * Description        : select using mon_a or mon_b
 *                      when monitored frequency is 600M~10M, use div_num_a(config to 0x3FF)
 *                      when monitored frequency is 10M~100K, use div_num_b(config to 0x27FF)
 * \endverbatim
 *******************************************************************************************************/
static uint8 Mcu_Ip_CkgenDbgMonSelectAorB(uint32 base, uint32 rate)
{
    uint32 ui32MonCtrlReg;
    uint8 monSrcSel;

    ui32MonCtrlReg =  readl(base + MON_CTL_OFF);

    /* when monitored frequency is 600M~10M, use div_num_a(config to 0x3FF)
    when monitored frequency is 10M~100K, use div_num_b(config to 0x27FF)*/
    if ((rate >= 100000U) && (rate < 10000000U))
    {
        ui32MonCtrlReg |= BM_MON_CTL_MON_CLK_SRC_SEL;
        monSrcSel = 1U;
    }
    else
    {
        ui32MonCtrlReg &= ~BM_MON_CTL_MON_CLK_SRC_SEL;
        monSrcSel = 0U;
    }

    writel(ui32MonCtrlReg, base + MON_CTL_OFF);

    return monSrcSel;
}

/** *****************************************************************************************************
 * \brief get bus slice m/n/p/q type and register address
 *
 * \verbatim
 * Syntax             : static uint32 Mcu_Ip_CkgenBusMonType(uint32 base, uint32 id, uint32 type, uint32 *busMonOutPtr)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - CKGEN base address
 *                      id - slice id
 *
 * Parameters (inout) :
 *                      busMonOutPtr - register address
 *
 * Parameters (out)   : None
 *
 * Return value       : upd bit
 *
 * Description        : get bus slice m/n/p/q type and register address
 * \endverbatim
 *******************************************************************************************************/
static uint32 Mcu_Ip_CkgenBusMonType(uint32 base, uint32 id, uint32 type, uint32 *busMonOutPtr)
{
    uint32 freqMonUpdBM;

    if (CKGEN_BUS_ID_TYPE_DIV_N == type)
    {
        freqMonUpdBM = BM_BUS_SLICE_MON_CTL_0_FREQ_MON_1_UPD;
        *busMonOutPtr = base + BUS_SLICE_MON_CTL_1_OFF(id);
    }
    else if (CKGEN_BUS_ID_TYPE_DIV_P == type)
    {
        freqMonUpdBM = BM_BUS_SLICE_MON_CTL_0_FREQ_MON_2_UPD;
        *busMonOutPtr = base + BUS_SLICE_MON_CTL_2_OFF(id);
    }
    else if (CKGEN_BUS_ID_TYPE_DIV_Q == type)
    {
        freqMonUpdBM = BM_BUS_SLICE_MON_CTL_0_FREQ_MON_3_UPD;
        *busMonOutPtr = base + BUS_SLICE_MON_CTL_2_OFF(id);
    }
    else
    {
        freqMonUpdBM = BM_BUS_SLICE_MON_CTL_0_FREQ_MON_0_UPD;
        *busMonOutPtr = base + BUS_SLICE_MON_CTL_1_OFF(id);
    }

    return freqMonUpdBM;
}

/** *****************************************************************************************************
 * \brief get ip slice interrupt status
 *
 * \verbatim
 * Syntax             : static boolean Mcu_Ip_CkgenIpGetIntState(uint32 base, uint32 id)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - CKGEN base address
 *                      id - ip slice id
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : TRUE- INTERRUPT, FALSE- NO INTERRUPT
 *
 * Description        : get ip slice interrupt status
 * \endverbatim
 *******************************************************************************************************/
static boolean Mcu_Ip_CkgenIpGetIntState(uint32 base, uint32 id)
{
    boolean ret;
    uint32 state = base + IP_CLK_INT_STA_OFF(id / 32U);

    if (0U == (readl(state) & (1UL << (id % 32U))))
    {
        ret = FALSE;
    }
    else
    {
        ret = TRUE;
    }

    return ret;
}

/** *****************************************************************************************************
 * \brief clear ip slice interrupt status
 *
 * \verbatim
 * Syntax             : static void Mcu_Ip_CkgenIpClearIntState(uint32 base, uint32 id)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - CKGEN base address
 *                      id - ip slice id
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : None
 *
 * Description        : clear ip slice interrupt status
 * \endverbatim
 *******************************************************************************************************/
static void Mcu_Ip_CkgenIpClearIntState(uint32 base, uint32 id)
{
    uint32 reg = base + IP_CLK_INT_STA_OFF(id / 32U);
    uint32 value = readl(reg);
    value &= ~(1UL << (id % 32U));
    writel(value, reg);
}

/** *****************************************************************************************************
 * \brief get bus slice interrupt status
 *
 * \verbatim
 * Syntax             : static boolean Mcu_Ip_CkgenBusGetIntState(uint32 base, uint32 id)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - CKGEN base address
 *                      id - bus slice id
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : status:0-no interrupt, 1- interrupt
 *
 * Description        : get bus slice interrupt status
 * \endverbatim
 *******************************************************************************************************/
static boolean Mcu_Ip_CkgenBusGetIntState(uint32 base, uint32 id)
{
    boolean ret;
    uint32 state = base + BUS_CLK_INT_STA_OFF;

    if (0U == (readl(state) & (1UL << (id % 32U))))
    {
        ret = FALSE;
    }
    else
    {
        ret = TRUE;
    }

    return ret;
}

/** *****************************************************************************************************
 * \brief clear bus slice interrupt status
 *
 * \verbatim
 * Syntax             : static void Mcu_Ip_CkgenBusClearIntState(uint32 base, uint32 id)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - CKGEN base address
 *                      id - bus slice id
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : None
 *
 * Description        : clear bus slice interrupt status
 * \endverbatim
 *******************************************************************************************************/
static void Mcu_Ip_CkgenBusClearIntState(uint32 base, uint32 id)
{
    uint32 reg = base + BUS_CLK_INT_STA_OFF;
    uint32 value = readl(reg);
    value &= ~(1UL << (id % 32U));
    writel(value, reg);
}

/** *****************************************************************************************************
 * \brief get 24M interrupt status
 *
 * \verbatim
 * Syntax             : static boolean Mcu_Ip_Ckgen24MGetIntState(uint32 base)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - CKGEN base address
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : TRUE- INTERRUPT, FALSE- NO INTERRUPT
 *
 * Description        : get 24M interrupt status
 * \endverbatim
 *******************************************************************************************************/
static boolean Mcu_Ip_Ckgen24MGetIntState(uint32 base)
{
    boolean ret;
    uint32 state = base + LOW_SPD_INT_STA_OFF;

    if (0U == (readl(state) & BM_LOW_SPD_INT_STA_INT_STA))
    {
        ret = FALSE;
    }
    else
    {
        ret = TRUE;
    }

    return ret;
}

/** *****************************************************************************************************
 * \brief clear 24M interrupt status
 *
 * \verbatim
 * Syntax             : static void Mcu_Ip_Ckgen24MClearIntState(uint32 base)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - CKGEN base address
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : None
 *
 * Description        : clear 24M interrupt status
 * \endverbatim
 *******************************************************************************************************/
static void Mcu_Ip_Ckgen24MClearIntState(uint32 base)
{
    uint32 reg = base + LOW_SPD_INT_STA_OFF;
    uint32 value = readl(reg);
    value &= ~BM_LOW_SPD_INT_STA_INT_STA;
    writel(value, reg);
}



/** *****************************************************************************************************
 * \brief get xtal timeout interrupt status
 *
 * \verbatim
 * Syntax             : static boolean Mcu_Ip_CkgenXtalGetIntState(uint32 base)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - CKGEN base address
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : TRUE- INTERRUPT, FALSE- NO INTERRUPT
 *
 * Description        : get xtal timeout interrupt status
 * \endverbatim
 *******************************************************************************************************/
static boolean Mcu_Ip_CkgenXtalGetIntState(uint32 base)
{
    boolean ret;
    uint32 state = base + XTAL_INT_STA_OFF;

    if (0U == (readl(state) & BM_XTAL_INT_STA_INT_STA_0))
    {
        ret = FALSE;
    }
    else
    {
        ret = TRUE;
    }

    return ret;
}

/** *****************************************************************************************************
 * \brief clear 24M interrupt status
 *
 * \verbatim
 * Syntax             : static void Mcu_Ip_CkgenXtalClearIntState(uint32 base)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - CKGEN base address
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : None
 *
 * Description        : clear 24M interrupt status
 * \endverbatim
 *******************************************************************************************************/
static void Mcu_Ip_CkgenXtalClearIntState(uint32 base)
{
    uint32 reg = base + XTAL_INT_STA_OFF;
    uint32 value = readl(reg);
    value &= ~BM_XTAL_INT_STA_INT_STA_0;
    writel(value, reg);
}

/** *****************************************************************************************************
 * \brief get pll timeout interrupt status
 *
 * \verbatim
 * Syntax             : static boolean Mcu_Ip_CkgenPllGetIntState(uint32 base, uint32 id)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - CKGEN base address
 *                      id - pll index
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : TRUE- INTERRUPT, FALSE- NO INTERRUPT
 *
 * Description        : get pll timeout interrupt status
 * \endverbatim
 *******************************************************************************************************/
static boolean Mcu_Ip_CkgenPllGetIntState(uint32 base, uint32 id)
{
    boolean ret;
    uint32 state = base + PLL_INT_STA_OFF;

    if (0U == (readl(state) & (1UL << id)))
    {
        ret = FALSE;
    }
    else
    {
        ret = TRUE;
    }

    return ret;
}

/** *****************************************************************************************************
 * \brief clear pll timeout status
 *
 * \verbatim
 * Syntax             : static void Mcu_Ip_CkgenPllClearIntState(uint32 base, uint32 id)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - CKGEN base address
 *                      id - pll index
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : None
 *
 * Description        : clear pll timeout status
 * \endverbatim
 *******************************************************************************************************/
static void Mcu_Ip_CkgenPllClearIntState(uint32 base, uint32 id)
{
    uint32 reg = base + PLL_INT_STA_OFF;
    uint32 value = readl(reg);
    value &= ~(1UL << id);
    writel(value, reg);
}

/** *****************************************************************************************************
 * \brief get XCG interrupt status
 *
 * \verbatim
 * Syntax             : static boolean Mcu_Ip_CkgenXCGGetIntState(uint32 base, uint32 id, uint32 type)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - CKGEN base address
 *                      id - xcg index
 *                      type - cgtype PCG 0, BCG 1
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : TRUE- INTERRUPT, FALSE- NO INTERRUPT
 *
 * Description        : get XCG interrupt status
 * \endverbatim
 *******************************************************************************************************/
static boolean Mcu_Ip_CkgenXCGGetIntState(uint32 base, uint32 id, uint32 type)
{
    boolean ret;
    uint32 reg = CKGEN_XCG_INT_STA_BASE(base, (id / 32U), type);

    if (0U == (readl(reg) & (1UL << (id % 32U))))
    {
        ret = FALSE;
    }
    else
    {
        ret = TRUE;
    }

    return ret;
}

/** *****************************************************************************************************
 * \brief clear XCG status
 *
 * \verbatim
 * Syntax             : static void Mcu_Ip_CkgenXCGClearIntState(uint32 base, uint32 id, uint32 type)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - CKGEN base address
 *                      id - xcg index
 *                      type - cgtype PCG 0, BCG 1
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : None
 *
 * Description        : clear XCG status
 * \endverbatim
 *******************************************************************************************************/
static void Mcu_Ip_CkgenXCGClearIntState(uint32 base, uint32 id, uint32 type)
{
    uint32 reg = CKGEN_XCG_INT_STA_BASE(base, (id / 32U), type);
    uint32 value = readl(reg);
    value &= ~(1UL << (id % 32U));
    writel(value, reg);
}

/** *****************************************************************************************************
 * \brief clean monitoring threshold
 *
 * \verbatim
 * Syntax             : static void Mcu_Ip_CkgenSetThrdIntValue(uint32 base, Mcu_CkgenType sliceType, uint8 typeIndex)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - CKGEN base address
 *                      sliceType - sliceType
 *                      typeIndex - typeIndex
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : None
 *
 * Description        : clean monitoring threshold
 * \endverbatim
 *******************************************************************************************************/
static void Mcu_Ip_CkgenSetThrdIntValue(uint32 base, Mcu_CkgenType sliceType, uint8 typeIndex)
{

    if (CKGEN_IP_SLICE_TYPE == sliceType)
    {
        /* clear mon thrd */
        writel(0xFFFF0000U, base + IP_SLICE_MON_THRD_OFF((uint32)typeIndex));
    }
    else if ((CKGEN_SF_BUS_SLICE_TYPE == sliceType) || (CKGEN_BUS_SLICE_TYPE == sliceType))
    {
        /* clear mon thrd */
        writel(0xFFFF0000U, base + BUS_SLICE_MON_0_THRD_OFF((uint32)typeIndex));
        writel(0xFFFF0000U, base + BUS_SLICE_MON_1_THRD_OFF((uint32)typeIndex));
        writel(0xFFFF0000U, base + BUS_SLICE_MON_2_THRD_OFF((uint32)typeIndex));
        writel(0xFFFF0000U, base + BUS_SLICE_MON_3_THRD_OFF((uint32)typeIndex));

    }
    else if (CKGEN_FS24M_TYPE == sliceType)
    {
        /* clear mon thrd */
        writel(0x0BB8007Du, base + LOW_SPD_CHK_THRD_OFF);
    }
    else
    {
        /*do nothing*/
    }

}

/** *****************************************************************************************************
 * \brief This function used for enable/disable xtal readiness checking.
 *
 * \verbatim
 * Syntax             : static Std_ReturnType Mcu_Ip_CkgenXtalMonEnable(uint32 base, uint32 timeOut, boolean enable)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - ckgen base(only APB_CKGEN_LP_BASE valid)
 *                      timeOut - xtal24M WDT timeout
 *                      enable - TRUE: enable, FALSE: disable
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : errorId
 *                      E_OK for success and others for failure.
 *
 * Description        : This function used for enable/disable xtal readiness checking. only ckgen lp can do xtal monitor.
 * \endverbatim
 *******************************************************************************************************/
static Std_ReturnType Mcu_Ip_CkgenXtalMonEnable(uint32 base, uint32 timeOut, boolean enable)
{
    Std_ReturnType errStatus = E_OK;
    boolean timeoutFlag;
    uint32 xtalMon;
    uint32 value;

    if (base == APB_CKGEN_LP_BASE)
    {
        xtalMon = base + XTAL_MON_CTL_OFF;
        value = readl(xtalMon);
        McuFaultInj_Mcu_Ip_CkgenXtalMonEnable_01();
        if ((TRUE == enable) && (BM_XTAL_MON_CTL_MON_EN != (value & BM_XTAL_MON_CTL_MON_EN)))
        {
            value &= ~FM_XTAL_MON_CTL_TOUT_VAL;
            value |= FV_XTAL_MON_CTL_TOUT_VAL(timeOut);
            value |= BM_XTAL_MON_CTL_MON_EN;

            writel(value, xtalMon);

            timeoutFlag = Mcu_Ip_WaitForBitTimes(xtalMon, BM_XTAL_MON_CTL_MON_EN_STA,
                (uint32)enable, CKGEN_WAIT_TIME);
            McuFaultInj_Mcu_Ip_CkgenXtalMonEnable_02();
            if (FALSE == timeoutFlag)
            {
                errStatus = MCU_E_TIMEOUT;
            }
        }
        else if ((FALSE == enable) && (BM_XTAL_MON_CTL_MON_EN == (value & BM_XTAL_MON_CTL_MON_EN)))
        {
            value &= ~BM_XTAL_MON_CTL_MON_EN;

            writel(value, xtalMon);

            timeoutFlag = Mcu_Ip_WaitForBitTimes(xtalMon, BM_XTAL_MON_CTL_MON_EN_STA,
                (uint32)enable, CKGEN_WAIT_TIME);
            McuFaultInj_Mcu_Ip_CkgenXtalMonEnable_03();
            if (FALSE == timeoutFlag)
            {
                errStatus = MCU_E_TIMEOUT;
            }
        }
        else
        {
            ; /* do nothing */
        }

        /* set unc enable*/
        xtalMon = base + XTAL_UNC_EN_OFF;
        writel(enable, xtalMon);
    }
    else
    {
        errStatus = MCU_E_PARAM_CONFIG;
    }


    return errStatus;
}

/** *****************************************************************************************************
 * \brief This function used for get xtal readiness status.
 *
 * \verbatim
 * Syntax             : static uint8 Mcu_Ip_CkgenXtalMonGetXtalState(uint32 base)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - ckgen base(only APB_CKGEN_LP_BASE valid)
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : 1-ready, 0-not ready
 *
 * Description        : This function used for enable/disable xtal readiness checking.
 * \endverbatim
 *******************************************************************************************************/
static uint8 Mcu_Ip_CkgenXtalMonGetXtalState(uint32 base)
{
    uint32 xtalMon = base + XTAL_MON_CTL_OFF;
    return (uint8)((readl(xtalMon) & BM_XTAL_MON_CTL_XTAL_CLK_RDY) >> 29U);
}

/** *****************************************************************************************************
 * \brief This function used for enable/disable pll lock monitor.
 *
 * \verbatim
 * Syntax             : static Std_ReturnType Mcu_Ip_CkgenPllMonEnable(uint32 base, uint32 id, uint32 timeOut, boolean enable)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - ckgen base(only APB_CKGEN_SAFETY_BASE valid)
 *                      id - pll index
 *                      timeOut - pll WDT timeout
 *                      enable - TRUE: enable, FALSE: disable
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : None
 *
 * Description        : This function used for enable/disable pll lock monitor. only ckgen saf can do pll monitor.
 * \endverbatim
 *******************************************************************************************************/
static Std_ReturnType Mcu_Ip_CkgenPllMonEnable(uint32 base, uint32 id, uint32 timeOut, boolean enable)
{
    Std_ReturnType errStatus = E_OK;
    uint32 monCtrl;
    uint32 value;

    if (base == APB_CKGEN_SAFETY_BASE)
    {
        monCtrl = base + PLL_MON_CTL_OFF(id);
        value = readl(monCtrl);
        McuFaultInj_Mcu_Ip_CkgenPllMonEnable_01();
        if ((TRUE == enable) && (BM_PLL_MON_CTL_MON_EN != (value & BM_PLL_MON_CTL_MON_EN)))
        {
            value &= ~FM_PLL_MON_CTL_TOUT_VAL;
            value |= FV_PLL_MON_CTL_TOUT_VAL(timeOut);
            value |= BM_PLL_MON_CTL_MON_EN;

            writel(value, monCtrl);
        }
        else if ((FALSE == enable) && (BM_PLL_MON_CTL_MON_EN == (value & BM_PLL_MON_CTL_MON_EN)))
        {
            value &= ~BM_XTAL_MON_CTL_MON_EN;

            writel(value, monCtrl);
        }
        else
        {
            ; /* do nothing */
        }

        /* set unc enable*/
        monCtrl = base + PLL_UNC_EN_OFF;
        value = readl(monCtrl);
        value &= ~(1UL << id);
        value |= ((uint32)enable << id);
        writel(value, monCtrl);
    }
    else
    {
        errStatus = MCU_E_PARAM_CONFIG;
    }

    return errStatus;
}

/** *****************************************************************************************************
 * \brief This function used for get pll ready status.
 *
 * \verbatim
 * Syntax             : static uint8 Mcu_Ip_CkgenPllMonGetState(uint32 base, uint32 id)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - ckgen base(only APB_CKGEN_SAFETY_BASE valid)
 *                      id - pll index
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : 1-ready, 0-not ready
 *
 * Description        : This function used for get pll ready status.
 * \endverbatim
 *******************************************************************************************************/
static uint8 Mcu_Ip_CkgenPllMonGetState(uint32 base, uint32 id)
{
    uint32 monCtrl = base + PLL_MON_CTL_OFF(id);
    return (uint8)((readl(monCtrl) & BM_PLL_MON_CTL_PLL_CLK_RDY) >> 31U);
}

/** *****************************************************************************************************
 * \brief cg Amonitor enable/disable
 *
 * \verbatim
 * Syntax             : static void Mcu_Ip_CkgenXcgAmonEnable(uint32 base, uint32 id, uint32 type, boolean en)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - CKGEN base address
 *                      id - cg id
 *                      type - cgtype PCG 0, BCG 1, CCG 2
 *                      en - enable/disable
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : None
 *
 * Description        : cg Amonitor enable/disable
 *                      Using 24M/div/4 as the monitoring frequency,
 *                      clk_24m_monc are used for clock active monitors inside CGs.
 * \endverbatim
 *******************************************************************************************************/
static void Mcu_Ip_CkgenXcgAmonEnable(uint32 base, uint32 id, uint32 type, boolean en)
{
    uint32 ctrlReg = Mcu_Ip_CkgenXcgGetCtrlReg(base, id, type);
    uint32 value = readl(ctrlReg);

    if (TRUE == en)
    {
        value |= BM_PCG_CTL_ACTIVE_MON_EN;
        writel(value, ctrlReg);

        /* set cor/unc enable/disable*/
        ctrlReg = CKGEN_XCG_COR_EN_BASE(base, (id / 32U), type);
        value = readl(ctrlReg);
        value |= (1UL << (id % 32U));
        writel(value, ctrlReg);

        ctrlReg = CKGEN_XCG_UNC_EN_BASE(base, (id / 32U), type);
        value = readl(ctrlReg);
        value |= (1UL << (id % 32U));
        writel(value, ctrlReg);
    }
    else
    {
        value &= ~BM_PCG_CTL_ACTIVE_MON_EN;
        writel(value, ctrlReg);

        /* set cor/unc enable/disable*/
        ctrlReg = CKGEN_XCG_COR_EN_BASE(base, (id / 32U), type);
        value = readl(ctrlReg);
        value &= ~(1UL << (id % 32U));
        writel(value, ctrlReg);

        ctrlReg = CKGEN_XCG_UNC_EN_BASE(base, (id / 32U), type);
        value = readl(ctrlReg);
        value &= ~(1UL << (id % 32U));
        writel(value, ctrlReg);
    }
}

/** *****************************************************************************************************
 * \brief cg Amonitor status get
 *
 * \verbatim
 * Syntax             : static uint8 Mcu_Ip_CkgenXcgGetAmonState(uint32 base, uint32 id, uint32 type)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - CKGEN base address
 *                      id - cg id
 *                      type - cgtype PCG 0, BCG 1, CCG 2
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : a_mon status: 1-clock active,0-clock gated
 *
 * Description        : cg Amonitor status get
 *                      Using 24M/div/4 as the monitoring frequency,
 *                      clk_24m_monc are used for clock active monitors inside CGs.
 * \endverbatim
 *******************************************************************************************************/
static uint8 Mcu_Ip_CkgenXcgGetAmonState(uint32 base, uint32 id, uint32 type)
{
    uint32 ctrlReg = Mcu_Ip_CkgenXcgGetCtrlReg(base, id, type);
    return (uint8)((readl(ctrlReg) & BM_PCG_CTL_ACTIVE_MON_STA) >> 4U);
}

/** *****************************************************************************************************
 * \brief debug sorce config.
 *
 * \verbatim
 * Syntax             : static void Mcu_Ip_CkgenDbgMonSrcConfig(uint32 base, uint8 src, uint32 id)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - CKGEN base address
 *                      src - type, 0-ip slice, 1-bus slice,2-core slice,3-ext clock
 *                      id - slice id
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : None
 *
 * Description        : debug sorce config.
 *
 * \endverbatim
 * Traceability       : SW_SM006
 *******************************************************************************************************/
static void Mcu_Ip_CkgenDbgMonSrcConfig(uint32 base, uint8 src, uint32 id)
{
    uint32 dbgMonSrc = base + DBG_MON_CLK_SRC_OFF;
    uint32 value = readl(dbgMonSrc);
    uint32 dbgMonCtl = base + DBG_MON_CTL_OFF;

    switch (src)
    {
    case 0U:
        value &= ~FM_DBG_MON_CLK_SRC_IP_CLK_SRC_SEL;
        value |= FV_DBG_MON_CLK_SRC_IP_CLK_SRC_SEL(id);
        writel(value, dbgMonSrc);
        break;
    case 1U:
        value &= ~FM_DBG_MON_CLK_SRC_BUS_CLK_SRC_SEL;
        value |= FV_DBG_MON_CLK_SRC_BUS_CLK_SRC_SEL(id);
        writel(value, dbgMonSrc);
        break;
    case 3U:
        value &= ~FM_DBG_MON_CLK_SRC_EXT_CLK_SRC_SEL;
        value |= FV_DBG_MON_CLK_SRC_EXT_CLK_SRC_SEL(id);
        writel(value, dbgMonSrc);
        break;
    default:
        /* do nothing */
        break;
    }
    value = readl(dbgMonCtl);
    value &= ~FM_DBG_MON_CTL_CLK_SEL;
    value |= ((uint32)src << 3UL);
    writel(value, dbgMonCtl);
}
/********************************************************************************************************
 *                                  Global Function Declarations                                        *
 *******************************************************************************************************/
/** *****************************************************************************************************
 * \brief Check that the value of register bit changes to the expected value within the specified time period.
 *
 * \verbatim
 * Syntax             : boolean Mcu_Ip_WaitForBitTimes(uint32 base, uint32 offset, uint32 val, uint32 count)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - base address
 *                      offset - offset
 *                      val - wait for value
 *                      count - number of cycle waits
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : TRUE:not timeout, FALSE:timeout
 *
 * Description        : Check that the value of register bit changes to the expected value within the specified time period.
 *
 * \endverbatim
 * Traceability       : SW_SM005
 *******************************************************************************************************/
boolean Mcu_Ip_WaitForBitTimes(uint32 base, uint32 offset, uint32 val, uint32 count)
{
    volatile uint32 timesOut = count;
    boolean ret;

    McuHook_Mcu_Ip_WaitForBitTimes();


    if (0U == val)
    {
        while ((timesOut != 0U) && (0U != (readl(base) & offset)))
        {
            /* PRQA S 3387 1 */
            timesOut--;
        }
    }
    else
    {
        while ((timesOut != 0U) && (offset != (readl(base) & offset)))
        {
            /* PRQA S 3387 1 */
            timesOut--;
        }
    }

    if (timesOut > 0U)
    {
        ret = TRUE;
    }
    else
    {
        ret = FALSE;
    }

    return ret;
}


/** *****************************************************************************************************
 * \brief bus slice ratio get
 *
 * \verbatim
 * Syntax             : static Mcu_CkgenRateType Mcu_Ip_CkgenBusGetRatio(uint32 base)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - CKGEN base address
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : ratio - 0:core/axi/apb 4/2/1, 1:core/axi/apb 2/2/1
 *
 * Description        : bus slice ratio get
 *
 * \endverbatim
 * Traceability       : SW_SM005
 *******************************************************************************************************/
Mcu_CkgenRateType Mcu_Ip_CkgenBusGetRatio(uint32 base)
{
    return (readl(base + CKGEN_RES_OFF) & 1U);
}

/** *****************************************************************************************************
 * \brief bus slice premux get
 *
 * \verbatim
 * Syntax             : uint8 Mcu_Ip_CkgenBusGetPreMux(uint32 base, uint32 id)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - CKGEN base address
 *                      id - index
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : premux
 *
 * Description        : bus slice premux get
 *
 * \endverbatim
 *******************************************************************************************************/
uint8 Mcu_Ip_CkgenBusGetPreMux(uint32 base, uint32 id)
{
    uint32 ctrlVal;
    uint32 srcSel;

    ctrlVal = readl(base + BUS_SLICE_CTL_OFF(id));

    srcSel = GFV_BUS_SLICE_CTL_CLK_SRC_SEL(ctrlVal);

    /* sel ck_in4 */
    if (0U != (srcSel & BM_BUS_SLICE_CTL_CLK_SRC_SEL_CLKIN4))
    {
        srcSel = 4U;
    }
    else
    {
        srcSel = (srcSel & 3U);
    }

    return (uint8)srcSel;

}

/** *****************************************************************************************************
 * \brief bus slice divroot rate get
 *
 * \verbatim
 * Syntax             : Mcu_CkgenRateType Mcu_Ip_CkgenBusDivRootGetRate(uint32 base, uint32 id, Mcu_CkgenRateType srcRate)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - CKGEN base address
 *                      id - bus slice id
 *                      srcRate - parent rate
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : bus slice divroot rate
 *
 * Description        : bus slice divroot rate get
 *
 * \endverbatim
 * Traceability       : SW_SM005
 *******************************************************************************************************/
Mcu_CkgenRateType Mcu_Ip_CkgenBusDivRootGetRate(uint32 base, uint32 id,
        Mcu_CkgenRateType srcRate)
{
    uint32 ctrlVal;
    uint32 srcSel;
    uint32 preDiv;
    Mcu_CkgenRateType rate;

    ctrlVal = readl(base + BUS_SLICE_CTL_OFF(id));

    srcSel = GFV_BUS_SLICE_CTL_CLK_SRC_SEL(ctrlVal);

    /* sel ck_in4 */
    if (0U != (srcSel & BM_BUS_SLICE_CTL_CLK_SRC_SEL_CLKIN4))
    {
        rate = srcRate;
    }
    /* sel ck_in0 ~ ck_in3 */
    else
    {
        preDiv = GFV_BUS_SLICE_CTL_DIV_NUM(ctrlVal);
        rate = (Mcu_CkgenRateType)srcRate / (Mcu_CkgenRateType)(preDiv + 1U);
    }

    return rate;
}

/** *****************************************************************************************************
 * \brief bus slice mnpq rate get
 *
 * \verbatim
 * Syntax             : Mcu_CkgenRateType Mcu_Ip_CkgenBusDivMnpqGetRate(uint32 base, uint32 id,
                                                Mcu_CkgenRateType srcRate)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - CKGEN base address
 *                      id - bus slice id
 *                      type - bus slice type
 *                      srcRate - parent rate
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : bus slice mnpq rate
 *
 * Description        : bus slice mnpq rate get
 *
 * \endverbatim
 * Traceability       : SW_SM005
 *******************************************************************************************************/
Mcu_CkgenRateType Mcu_Ip_CkgenBusDivMnpqGetRate(uint32 base, uint32 id, uint32 type,
        Mcu_CkgenRateType srcRate)
{
    uint32 syncCtrl = base + BUS_SLICE_SYNC_CTL_OFF(id);
    uint32 val;
    uint32 divNum;
    uint32 rate = UINT32_MAX;

    val = readl(syncCtrl);

    switch (type)
    {
    case CKGEN_BUS_ID_TYPE_DIV_M:
        divNum = GFV_BUS_SLICE_SYNC_CTL_DIV_M_NUM(val);
        rate = (Mcu_CkgenRateType)srcRate / (Mcu_CkgenRateType)(divNum + 1U);
        break;
    case CKGEN_BUS_ID_TYPE_DIV_N:
        divNum = GFV_BUS_SLICE_SYNC_CTL_DIV_N_NUM(val);
        rate = (Mcu_CkgenRateType)srcRate / (Mcu_CkgenRateType)(divNum + 1U);
        break;
    case CKGEN_BUS_ID_TYPE_DIV_P:
        divNum = GFV_BUS_SLICE_SYNC_CTL_DIV_P_NUM(val);
        rate = (Mcu_CkgenRateType)srcRate / (Mcu_CkgenRateType)(divNum + 1U);
        break;
    case CKGEN_BUS_ID_TYPE_DIV_Q:
        divNum = GFV_BUS_SLICE_SYNC_CTL_DIV_Q_NUM(val);
        rate = (Mcu_CkgenRateType)srcRate / (Mcu_CkgenRateType)(divNum + 1U);
        break;
    default:
        /* do nothing */
        break;
    }

    return rate;
}

/** *****************************************************************************************************
 * \brief bus slice root set rate
 *
 * \verbatim
 * Syntax             : Std_ReturnType Mcu_Ip_CkgenBusRootSetRate(uint32 base, uint32 id, uint8 mux)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - CKGEN base address
 *                      id - bus slice id
 *                      mux - mux
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : errID
 *
 * Description        : bus slice root set rate.
 *                      mux0 - out is from m
 *                      mux1 - out is from pll
 * .
 * \endverbatim
 * Traceability       : SW_SM005
 *******************************************************************************************************/
Std_ReturnType Mcu_Ip_CkgenBusRootSetRate(uint32 base, uint32 id, uint8 mux)
{
    Std_ReturnType errStatus = E_OK;
    uint8 flag;
    boolean timeoutFlag;
    uint32 value = readl(base + BUS_SLICE_CTL_OFF(id));

    /* Make sure CG is enabled. */
    if (1U == mux)
    {
        flag = 0U;
        value |= BM_BUS_SLICE_CTL_MAIN_EN;
        writel(value, (base + BUS_SLICE_CTL_OFF(id)));

        timeoutFlag = Mcu_Ip_WaitForBitTimes((base + BUS_SLICE_CTL_OFF(id)), BM_BUS_SLICE_CTL_MAIN_EN_STATUS,
                                            1U, CKGEN_WAIT_TIME);
        McuFaultInj_Mcu_Ip_CkgenBusRootSetRate_01();
        if (FALSE == timeoutFlag)
        {
            errStatus = MCU_E_TIMEOUT;
        }
        else
        {
            value = readl(base + BUS_SLICE_CTL_OFF(id));
            value |= BM_BUS_SLICE_CTL_CLK_SRC_SEL_BIT3;
            writel(value, (base + BUS_SLICE_CTL_OFF(id)));
            timeoutFlag = Mcu_Ip_WaitForBitTimes((base + BUS_SLICE_CTL_OFF(id)), BM_BUS_SLICE_CTL_POST_MUX_D0_ACTIVE,
                                            flag, CKGEN_WAIT_TIME);
            McuFaultInj_Mcu_Ip_CkgenBusRootSetRate_02();
            if (FALSE == timeoutFlag)
            {
                errStatus = MCU_E_TIMEOUT;
            } /* else not needed */
        }
    }
    else
    {
        flag = 1U;
        value = readl(base + BUS_SLICE_CTL_OFF(id));
        value &= ~BM_BUS_SLICE_CTL_CLK_SRC_SEL_BIT3;
        writel(value, (base + BUS_SLICE_CTL_OFF(id)));
        timeoutFlag = Mcu_Ip_WaitForBitTimes((base + BUS_SLICE_CTL_OFF(id)), BM_BUS_SLICE_CTL_POST_MUX_D0_ACTIVE,
                                        flag, CKGEN_WAIT_TIME);
        if (FALSE == timeoutFlag)
        {
            errStatus = MCU_E_TIMEOUT;
        } /* else not needed */
    }

    return errStatus;
}
/** *****************************************************************************************************
 * \brief bus slice divroot set rate
 *
 * \verbatim
 * Syntax             : Std_ReturnType Mcu_Ip_CkgenBusDivRootSetRate(uint32 base, Mcu_CkgenType type, uint32 id, uint8 mux, uint32 divNum)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - CKGEN base address
 *                      type - bus slice type
 *                      id - bus slice id
 *                      mux - mux
 *                      divNum - divNum
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : errID
 *
 * Description        : bus slice divroot set rate.
 *                      Preset core:axi:bus 4:2:1 to avoid freq is too high when switch to clkin4 momentary.
 *                      Preset div m/n/p to avoid freq is too high.
 *                      When switching between 0~3 and 4, ensure that both are active before switching;
 *                      When switching between 0~3, ensure that pre-en is off;
 *                      clkin4 do not have pre-div.
 * .
 * \endverbatim
 * Traceability       : SW_SM005 SW_MCU_SM012
 *******************************************************************************************************/
Std_ReturnType Mcu_Ip_CkgenBusDivRootSetRate(uint32 base, Mcu_CkgenType type, uint32 id, uint8 mux,
        uint32 divNum)
{
    uint32 value;
    uint32 waitTimeoutFlag;
    Std_ReturnType errStatus;

    /* set div m/n/p to avoid freq is too high */
    errStatus = Mcu_Ip_CkgenBusSliceSetMnpqDivOnetime(base, id, 2U, 4U, 8U, 0U);

    McuFaultInj_Mcu_Ip_CkgenBusDivRootSetRate_01();

    if (E_OK == errStatus)
    {
        /* for CKGEN_SF_BUS_SLICE_TYPE, set 4:2:1 avoid axi bus overclocking */
        if (CKGEN_SF_BUS_SLICE_TYPE == type)
        {
            Mcu_Ip_CkgenSetRatio(base, CKGEN_BUS_DIV_4_2_1);
        }

        /* set pre mux */
        errStatus = Mcu_Ip_CkgenBusSliceSetPreMux(base, id, mux);

        if (E_OK == errStatus)
        {
            if (mux != 4U)
            {
                /* set pre-mux when pre-en is 1, otherwise BUSY bit cannot change  */
                value = readl(base + BUS_SLICE_CTL_OFF(id));
                value &= ~FM_BUS_SLICE_CTL_DIV_NUM;
                value |= FV_BUS_SLICE_CTL_DIV_NUM(divNum - 1U);
                writel(value, (base + BUS_SLICE_CTL_OFF(id)));

                waitTimeoutFlag = Mcu_Ip_WaitForBitTimes((base + BUS_SLICE_CTL_OFF(id)), BM_BUS_SLICE_CTL_DIV_CHG_BUSY,
                0U, CKGEN_WAIT_TIME);
                McuFaultInj_Mcu_Ip_CkgenBusDivRootSetRate_02();
                if (FALSE == waitTimeoutFlag)
                {
                    errStatus = MCU_E_TIMEOUT;
                } /* else not needed */

            } /* else not needed */
        } /* else not needed */
    } /* else not needed */

    return errStatus;
}
/** *****************************************************************************************************
 * \brief bus slice set rate
 *
 * \verbatim
 * Syntax             : Std_ReturnType Mcu_Ip_CkgenBusMnpqSetRate(uint32 base, uint32 id, Mcu_ClkBusRatioType postDiv, uint32 mDiv)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - CKGEN base address
 *                      id - bus slice id
 *                      postDiv - cpu:axi:apb ratio
 *                      mDiv - m div
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : errID
 *
 * Description        : bus slice set rate
 *
 * \endverbatim
 *******************************************************************************************************/
Std_ReturnType Mcu_Ip_CkgenBusMnpqSetRate(uint32 base, uint32 id, Mcu_ClkBusRatioType postDiv, uint32 mDiv)
{
    Std_ReturnType errStatus;

    /* set div_m for clk_out */
    errStatus = Mcu_Ip_CkgenBusDivMnpqSetRate(base, id, CKGEN_BUS_ID_TYPE_DIV_M, mDiv);

    if (E_OK == errStatus)
    {
        /* set div_n, div_p according to post ratio. Actually, n/p not be used. */
        if (CKGEN_BUS_DIV_4_2_1 == postDiv)
        {
            errStatus = Mcu_Ip_CkgenBusDivMnpqSetRate(base, id, CKGEN_BUS_ID_TYPE_DIV_N, (2U * mDiv));
            errStatus |= Mcu_Ip_CkgenBusDivMnpqSetRate(base, id, CKGEN_BUS_ID_TYPE_DIV_P, (4U * mDiv));
        }
        else
        {
            errStatus = Mcu_Ip_CkgenBusDivMnpqSetRate(base, id, CKGEN_BUS_ID_TYPE_DIV_N, mDiv);
            errStatus |= Mcu_Ip_CkgenBusDivMnpqSetRate(base, id, CKGEN_BUS_ID_TYPE_DIV_P, (2U * mDiv));
        }

        /* set post div */
        Mcu_Ip_CkgenSetRatio(base, postDiv);
    }

    return errStatus;
}

/** *****************************************************************************************************
 * \brief ip slice mux get
 *
 * \verbatim
 * Syntax             : uint8 Mcu_Ip_CkgenIpGetMux(uint32 base, uint32 id)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - CKGEN base address
 *                      id - ip slice id
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : mux
 *
 * Description        : ip slice mux get
 *
 * \endverbatim
 *******************************************************************************************************/
uint8 Mcu_Ip_CkgenIpGetMux(uint32 base, uint32 id)
{
    uint32 ctrlReg = base + IP_SLICE_CTL_OFF(id);
    uint32 ctrlVal;
    uint32 mux;

    ctrlVal = readl(ctrlReg);

    mux = GFV_IP_SLICE_CTL_CLK_SRC_SEL(ctrlVal);

    /* sel ck_in4 */
    if (0U != (mux & BM_IP_SLICE_CTL_CLK_SRC_SEL_CLKIN4))
    {
        mux = 4U;
    }
    else
    {
        mux = (mux & 3U);
    }

    return (uint8)mux;
}

/** *****************************************************************************************************
 * \brief ip slice div get
 *
 * \verbatim
 * Syntax             : uint32 Mcu_Ip_CkgenIpGetDiv(uint32 base, uint32 id)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - CKGEN base address
 *                      id - ip slice id
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : div
 *
 * Description        : ip slice div get
 *
 * \endverbatim
 *******************************************************************************************************/
uint32 Mcu_Ip_CkgenIpGetDiv(uint32 base, uint32 id)
{
    uint32 ctrlReg = base + IP_SLICE_CTL_OFF(id);
    uint32 ctrlVal;
    uint32 divNum;

    ctrlVal = readl(ctrlReg);

    divNum = GFV_IP_SLICE_CTL_DIV_NUM(ctrlVal);

    return divNum;
}

/** *****************************************************************************************************
 * \brief ip slice set rate
 *
 * \verbatim
 * Syntax             : Std_ReturnType Mcu_Ip_CkgenIpSetRate(uint32 base, uint32 id, uint8 mux, uint32 divNum)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - CKGEN base address
 *                      id - ip slice id
 *                      mux - mux
 *                      divNum - divNum
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : errID
 *
 * Description        : ip slice set rate
 *                      Preset div to avoid freq is too high when switch to clkin4 momentary.
 *                      When switching between 0~3 and 4, ensure that both are active before switching;
 *                      When switching between 0~3, ensure that pre-en is off;
 * .
 * \endverbatim
 * Traceability       : SW_MCU_SM013
 *******************************************************************************************************/
Std_ReturnType Mcu_Ip_CkgenIpSetRate(uint32 base, uint32 id, uint8 mux, uint32 divNum)
{
    Std_ReturnType errStatus;

    /* set div to avoid freq is too high */
    errStatus = Mcu_Ip_CkgenIpSetDiv(base, id, 0x7FU);

    if (E_OK == errStatus)
    {
        /* change slice parent */
        errStatus = Mcu_Ip_CkgenIpSetMux(base, id, mux);

        if (E_OK == errStatus)
        {
            /* set div after change mux */
            errStatus = Mcu_Ip_CkgenIpSetDiv(base, id, divNum);
        } /* else not needed */
    } /* else not needed */

    return errStatus;
}

/** *****************************************************************************************************
 * \brief Clock gate turn on/off in run mode.
 *
 * \verbatim
 * Syntax             : Std_ReturnType Mcu_Ip_CkgenXcgSetGating(uint32 base, uint32 id, uint32 type, boolean en)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - CKGEN base address
 *                      id - clock gate id
 *                      type - cgtype PCG 0, BCG 1, CCG 2
 *                      en - 1:on, 0:off
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : errID
 *
 * Description        : Clock gate turn on/off in runr mode.
 *
 * \endverbatim
 * Traceability       : SW_SM006
 *******************************************************************************************************/
Std_ReturnType Mcu_Ip_CkgenXcgSetGating(uint32 base, uint32 id, uint32 type, boolean en)
{
    uint32 ctrlReg = Mcu_Ip_CkgenXcgGetCtrlReg(base, id, type);
    uint32 value = readl(ctrlReg);
    Std_ReturnType errStatus = MCU_E_PARAM_CONFIG;

    if ((CKGEN_CG_ID_TYPE_PCG_TYPE == type) || (CKGEN_CG_ID_TYPE_BCG_TYPE == type))
    {
        value &= ~BM_PCG_CTL_RUN_MODE;
        value |= ((uint32)en);
        writel(value, ctrlReg);
        errStatus = E_OK;
    } /* else not needed */

    return errStatus;
}

/** *****************************************************************************************************
 * \brief Clk check gated state.
 *
 * \verbatim
 * Syntax             : boolean Mcu_Ip_CkgenXcgIsGated(uint32 base, uint32 id, uint32 type)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - CKGEN base address
 *                      id - clock gate id
 *                      type - cgtype PCG 0, BCG 1, CCG 2
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : clock gate state
 *
 * Description        : get the clock gate state in run mode.
 *                      return 1 means gated, 0 means active.
 *
 * \endverbatim
 * Traceability       : SW_SM006
 *******************************************************************************************************/
boolean Mcu_Ip_CkgenXcgIsGated(uint32 base, uint32 id, uint32 type)
{
    boolean ret;
    uint32 ctrlReg = Mcu_Ip_CkgenXcgGetCtrlReg(base, id, type);

    if (0U != (readl(ctrlReg) & BM_PCG_CTL_CG_GATED))
    {
        ret = TRUE;
    }
    else
    {
        ret = FALSE;
    }

    return ret;
}

/** *****************************************************************************************************
 * \brief get interrupt status
 *
 * \verbatim
 * Syntax             : uint8 Mcu_Ip_CkgenGetIntStatus(uint32 base, Mcu_CkgenType sliceType, uint32 typeIndex)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - CKGEN base address
 *                      sliceType - sliceType
 *                      typeIndex - typeIndex
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : TRUE- INTERRUPT, FALSE- NO INTERRUPT
 *
 * Description        : get interrupt status
 * \endverbatim
 *******************************************************************************************************/
uint8 Mcu_Ip_CkgenGetIntStatus(uint32 base, Mcu_CkgenType sliceType, uint32 typeIndex)
{
    uint8 status = 0xFFU;

    switch (sliceType)
    {
    case CKGEN_IP_SLICE_TYPE:
        /* clear mon int flag */
        status = Mcu_Ip_CkgenIpGetIntState(base, typeIndex);
        break;

    case CKGEN_SF_BUS_SLICE_TYPE:
    case CKGEN_BUS_SLICE_TYPE:
        /* clear mon int flag */
        status = Mcu_Ip_CkgenBusGetIntState(base, typeIndex);
        break;

    case CKGEN_FS24M_TYPE:
        /* clear mon int flag */
        status = Mcu_Ip_Ckgen24MGetIntState(base);
        break;

    case CKGEN_PCG_TYPE:
        /* clear mon int flag */
        status = Mcu_Ip_CkgenXCGGetIntState(base, typeIndex, CKGEN_CG_ID_TYPE_PCG_TYPE);
        break;

    case CKGEN_BCG_TYPE:
        /* clear mon int flag */
        status = Mcu_Ip_CkgenXCGGetIntState(base, typeIndex, CKGEN_CG_ID_TYPE_BCG_TYPE);
        break;

    case CKGEN_PLL_CG_TYPE:
        /* clear mon int flag */
        status = Mcu_Ip_CkgenPllGetIntState(base, typeIndex);
        break;

    case CKGEN_XTAL_CG_TYPE:
        /* clear mon int flag */
        status = Mcu_Ip_CkgenXtalGetIntState(base);
        break;

    default:
        /*do nothing */
        break;
    }

    return status;
}
/** *****************************************************************************************************
 * \brief clear interrupt status
 *
 * \verbatim
 * Syntax             : void Mcu_Ip_CkgenClearIntStatus(uint32 base, Mcu_CkgenType sliceType, uint32 typeIndex)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - CKGEN base address
 *                      sliceType - sliceType
 *                      typeIndex - typeIndex
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : None
 *
 * Description        : clear interrupt status
 * \endverbatim
 *******************************************************************************************************/
void Mcu_Ip_CkgenClearIntStatus(uint32 base, Mcu_CkgenType sliceType, uint32 typeIndex)
{
    switch (sliceType)
    {
    case CKGEN_IP_SLICE_TYPE:
        /* clear mon int flag */
        Mcu_Ip_CkgenIpClearIntState(base, typeIndex);
        break;

    case CKGEN_SF_BUS_SLICE_TYPE:
    case CKGEN_BUS_SLICE_TYPE:
        /* clear mon int flag */
        Mcu_Ip_CkgenBusClearIntState(base, typeIndex);
        break;

    case CKGEN_FS24M_TYPE:
        /* clear mon int flag */
        Mcu_Ip_Ckgen24MClearIntState(base);
        break;

    case CKGEN_PCG_TYPE:
        /* clear mon int flag */
        Mcu_Ip_CkgenXCGClearIntState(base, typeIndex, CKGEN_CG_ID_TYPE_PCG_TYPE);
        break;

    case CKGEN_BCG_TYPE:
        /* clear mon int flag */
        Mcu_Ip_CkgenXCGClearIntState(base, typeIndex, CKGEN_CG_ID_TYPE_BCG_TYPE);
        break;

    case CKGEN_PLL_CG_TYPE:
        /* clear mon int flag */
        Mcu_Ip_CkgenPllClearIntState(base, typeIndex);
        break;

    case CKGEN_XTAL_CG_TYPE:
        /* clear mon int flag */
        Mcu_Ip_CkgenXtalClearIntState(base);
        break;

    default:
        /*do nothing */
        break;
    }
}

/** *****************************************************************************************************
 * \brief get ready state
 *
 * \verbatim
 * Syntax             : uint8 Mcu_Ip_CkgenGetReadyState(uint32 base, Mcu_CkgenType sliceType, uint32 typeIndex)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - CKGEN base address
 *                      sliceType - sliceType
 *                      typeIndex - typeIndex
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : 1-ready, 0-not ready
 *
 * Description        : get ready state
 *
 * \endverbatim
 *******************************************************************************************************/
uint8 Mcu_Ip_CkgenGetReadyState(uint32 base, Mcu_CkgenType sliceType, uint32 typeIndex)
{
    uint8 state = 0xFFU;

    switch (sliceType)
    {
    case CKGEN_PCG_TYPE:
        state = Mcu_Ip_CkgenXcgGetAmonState(base, typeIndex, CKGEN_CG_ID_TYPE_PCG_TYPE);
        break;

    case CKGEN_BCG_TYPE:
        state = Mcu_Ip_CkgenXcgGetAmonState(base, typeIndex, CKGEN_CG_ID_TYPE_BCG_TYPE);
        break;

    case CKGEN_PLL_CG_TYPE:
        state = Mcu_Ip_CkgenPllMonGetState(base, typeIndex);
        break;

    case CKGEN_XTAL_CG_TYPE:
        state = Mcu_Ip_CkgenXtalMonGetXtalState(base);
        break;

    default:
        /*do nothing */
        break;
    }

    return state;
}
/** *****************************************************************************************************
 * \brief clear monitor threshold and interrupt status
 *
 * \verbatim
 * Syntax             : void Mcu_Ip_CkgenSliceMonClrBusErrStatus(uint32 base, Mcu_CkgenType sliceType, uint8 typeIndex)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - CKGEN base address
 *                      sliceType - sliceType
 *                      typeIndex - typeIndex
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : None
 *
 * Description        : clear monitor threshold and interrupt status
 * \endverbatim
 *******************************************************************************************************/
void Mcu_Ip_CkgenSliceMonClrBusErrStatus(uint32 base, Mcu_CkgenType sliceType,
        uint8 typeIndex)
{
    Mcu_Ip_CkgenSetThrdIntValue(base, sliceType, typeIndex);
    Mcu_Ip_CkgenClearIntStatus(base, sliceType, typeIndex);
}

/** *****************************************************************************************************
 * \brief ip slice debug sorce config.
 *
 * \verbatim
 * Syntax             : void Mcu_Ip_CkgenDbgMonIpSelect(uint32 base, uint32 id, uint8 divNum))
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - CKGEN base address
 *                      id - slice id
 *                      divNum - divNum
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : None
 *
 * Description        : ip slice debug sorce config.
 *
 * \endverbatim
 * Traceability       : SW_SM006
 *******************************************************************************************************/
void Mcu_Ip_CkgenDbgMonIpSelect(uint32 base, uint32 id, uint8 divNum)
{
    uint32 ipCtrl = base + IP_SLICE_CTL_OFF(id);
    uint32 dbgMonCtl = base + DBG_MON_CTL_OFF;
    uint32 dbgCtl = base + DBG_CTL_OFF;
    uint32 value = readl(dbgCtl);

    value &= ~FM_DBG_CTL_DIV_NUM;
    value |= FV_DBG_CTL_DIV_NUM(((uint32)divNum - 1UL));
    writel(value, dbgCtl);

    value = readl(ipCtrl);
    value |= BM_IP_SLICE_CTL_DBG_EN;
    writel(value, ipCtrl);

    Mcu_Ip_CkgenDbgMonSrcConfig(base, 0U, id);

    value = readl(dbgMonCtl);
    value |= BM_DBG_MON_CTL_DBG_GATING_EN;
    writel(value, dbgMonCtl);
}

/** *****************************************************************************************************
 * \brief bus slice debug sorce config.
 *
 * \verbatim
 * Syntax             : void Mcu_Ip_CkgenDbgMonBusSelect(uint32 base, uint32 id, uint8 divNum))
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - CKGEN base address
 *                      id - slice id
 *                      divNum - divNum
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : None
 *
 * Description        : bus slice debug sorce config.
 *
 * \endverbatim
 * Traceability       : SW_SM006
 *******************************************************************************************************/
void Mcu_Ip_CkgenDbgMonBusSelect(uint32 base, uint32 id, uint8 divNum)
{
    uint32 busCtrl = base + BUS_SLICE_CTL_OFF(id);
    uint32 dbgMonCtl = base + DBG_MON_CTL_OFF;
    uint32 dbgCtl = base + DBG_CTL_OFF;
    uint32 value = readl(dbgCtl);

    value &= ~FM_DBG_CTL_DIV_NUM;
    value |= FV_DBG_CTL_DIV_NUM(((uint32)divNum - 1UL));
    writel(value, dbgCtl);

    value = readl(busCtrl);
    value |= BM_BUS_SLICE_CTL_DBG_EN;
    writel(value, busCtrl);

    Mcu_Ip_CkgenDbgMonSrcConfig(base, 1U, id);

    value = readl(dbgMonCtl);
    value |= BM_DBG_MON_CTL_DBG_GATING_EN;
    writel(value, dbgMonCtl);

}

/** *****************************************************************************************************
 * \brief ext clk debug sorce config.
 *
 * \verbatim
 * Syntax             : void Mcu_Ip_CkgenDbgMonExtSelect(uint32 base, uint32 id, uint8 divNum)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - CKGEN base address
 *                      id - slice id
 *                      divNum - divNum
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : None
 *
 * Description        : ext clk debug sorce config.
 *
 * \endverbatim
 * Traceability       : SW_SM006
 *******************************************************************************************************/
void Mcu_Ip_CkgenDbgMonExtSelect(uint32 base, uint32 id, uint8 divNum)
{
    uint32 dbgMonCtl = base + DBG_MON_CTL_OFF;
    uint32 dbgCtl = base + DBG_CTL_OFF;
    uint32 value = readl(dbgCtl);

    value &= ~FM_DBG_CTL_DIV_NUM;
    value |= FV_DBG_CTL_DIV_NUM(((uint32)divNum - 1UL));
    writel(value, dbgCtl);

    Mcu_Ip_CkgenDbgMonSrcConfig(base, 3U, id);

    if (APB_CKGEN_SAFETY_BASE == base)
    {
        if ((6U == id) || (7U == id))
        {
            value = readl(base + BCG_CTL_OFF(0U));
            value |= BM_BCG_CTL_DBG_EN;
            writel(value, (base + BCG_CTL_OFF(0U)));
        }
        else if((8U == id) || (9U == id))
        {
            value = readl(base + BCG_CTL_OFF(5U));
            value |= BM_BCG_CTL_DBG_EN;
            writel(value, (base + BCG_CTL_OFF(5U)));
        }
        else
        {
            ; /*do nothing */
        }
    }
    else
    {
        if ((0U == id) || (1U == id))
        {
            value = readl(base + BCG_CTL_OFF(0U));
            value |= BM_BCG_CTL_DBG_EN;
            writel(value, (base + BCG_CTL_OFF(0U)));
        }
        else if ((2U == id) || (3U == id))
        {
            value = readl(base + PCG_CTL_OFF(71U));
            value |= BM_PCG_CTL_DBG_EN;
            writel(value, (base + PCG_CTL_OFF(71U)));

            value = readl(base + PCG_CTL_OFF(72U));
            value |= BM_PCG_CTL_DBG_EN;
            writel(value, (base + PCG_CTL_OFF(72U)));
        }
        else
        {
            ; /*do nothing */
        }
    }

    value = readl(dbgMonCtl);
    value |= BM_DBG_MON_CTL_DBG_GATING_EN;
    writel(value, dbgMonCtl);
}

/** *****************************************************************************************************
 * \brief get dbgMon interrupt status
 *
 * \verbatim
 * Syntax             : boolean Mcu_Ip_CkgenDbgMonGetIntState(uint32 base)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - CKGEN base address
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : TRUE- INTERRUPT, FALSE- NO INTERRUPT
 *
 * Description        : get dbgMon interrupt status
 * \endverbatim
 *******************************************************************************************************/
boolean Mcu_Ip_CkgenDbgMonGetIntState(uint32 base)
{
    boolean ret;
    uint32 state = base + MON_INT_STA_OFF;

    if (0U == (readl(state) & BM_MON_INT_STA_INT_STA))
    {
        ret = FALSE;
    }
    else
    {
        ret = TRUE;
    }

    return ret;
}

/** *****************************************************************************************************
 * \brief clear dbgMon interrupt status
 *
 * \verbatim
 * Syntax             : void Mcu_Ip_CkgenDbgMonClearIntState(uint32 base)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - CKGEN base address
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : None
 *
 * Description        : clear dbgMon interrupt status
 * \endverbatim
 *******************************************************************************************************/
void Mcu_Ip_CkgenDbgMonClearIntState(uint32 base)
{
    uint32 reg = base + MON_INT_STA_OFF;
    uint32 value = readl(reg);

    value &= ~BM_MON_INT_STA_INT_STA;
    writel(value, reg);
}

/** *****************************************************************************************************
 * \brief dbgMon sorce config.
 *
 * \verbatim
 * Syntax             : void Mcu_Ip_CkgenDbgMonSelect(uint32 base, uint8 type, uint32 id)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - CKGEN base address
 *                      type - slice type
 *                      id - slice id
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : None
 *
 * Description        : dbgMon sorce config.
 *
 * \endverbatim
 *******************************************************************************************************/
void Mcu_Ip_CkgenDbgMonSelect(uint32 base, uint8 type, uint32 id)
{
    uint32 dbgMonCtl = base + DBG_MON_CTL_OFF;
    uint32 value;

    Mcu_Ip_CkgenDbgMonSrcConfig(base, type, id);
    value = readl(dbgMonCtl);
    value |= BM_DBG_MON_CTL_MON_GATING_EN;
    writel(value, dbgMonCtl);
}

/** *****************************************************************************************************
 * \brief get duty interrupt state.
 *
 * \verbatim
 * Syntax             : boolean Mcu_Ip_CkgenCqmGetDutyIntState(uint32 base, uint32 id)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - CKGEN base address
 *                      id - index
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : TRUE- INTERRUPT, FALSE- NO INTERRUPT
 *
 * Description        : get duty interrupt state.
 *
 * \endverbatim
 *******************************************************************************************************/
boolean Mcu_Ip_CkgenCqmGetDutyIntState(uint32 base, uint32 cqmIndex)
{
    boolean ret;
    uint32 value = (readl(base + CQM_DUTY_INT_STA_OFF) & (1UL << cqmIndex));

    if (0U == value)
    {
        ret = FALSE;
    }
    else
    {
        ret = TRUE;
    }

    return ret;
}

/** *****************************************************************************************************
 * \brief get jitter interrupt state.
 *
 * \verbatim
 * Syntax             : boolean Mcu_Ip_CkgenCqmGetJitterIntState(uint32 base, uint32 id)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - CKGEN base address
 *                      id - index
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : TRUE- INTERRUPT, FALSE- NO INTERRUPT
 *
 * Description        : get duty interrupt state.
 *
 * \endverbatim
 *******************************************************************************************************/
boolean Mcu_Ip_CkgenCqmGetJitterIntState(uint32 base, uint32 cqmIndex)
{
    boolean ret;
    uint32 value = (readl(base + CQM_JITTER_INT_STA_OFF) & (1UL << cqmIndex));

    if (0U == value)
    {
        ret = FALSE;
    }
    else
    {
        ret = TRUE;
    }

    return ret;
}

/** *****************************************************************************************************
 * \brief clear duty interrupt state.
 *
 * \verbatim
 * Syntax             : void Mcu_Ip_CkgenCqmClearDutyIntState(uint32 base, uint32 id)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - CKGEN base address
 *                      id - index
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : None
 *
 * Description        : clear duty interrupt state.
 *
 * \endverbatim
 *******************************************************************************************************/
void Mcu_Ip_CkgenCqmClearDutyIntState(uint32 base, uint32 cqmIndex)
{
    uint32 value = readl(base + CQM_DUTY_INT_STA_OFF);

    value &= ~(1UL << cqmIndex);
    writel(value, (base + CQM_DUTY_INT_STA_OFF));
}

/** *****************************************************************************************************
 * \brief clear jitter interrupt state.
 *
 * \verbatim
 * Syntax             : void Mcu_Ip_CkgenCqmClearJitterIntState(uint32 base, uint32 id)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - CKGEN base address
 *                      id - index
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : None
 *
 * Description        : clear jitter interrupt state.
 *
 * \endverbatim
 *******************************************************************************************************/
void Mcu_Ip_CkgenCqmClearJitterIntState(uint32 base, uint32 cqmIndex)
{
    uint32 value = readl(base + CQM_JITTER_INT_STA_OFF);

    value &= ~(1UL << cqmIndex);
    writel(value, (base + CQM_JITTER_INT_STA_OFF));
}

/** *****************************************************************************************************
 * \brief Setting the ip slice monitoring threshold
 *
 * \verbatim
 * Syntax             : void Mcu_Ip_CkgenIpMonSetThrd(uint32 base, uint32 id,
                                      uint16 lowThrd, uint16 highThrd)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - CKGEN base address
 *                      id - slice id
 *                      lowThrd - lowThrd
 *                      highThrd - highThrd
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : None
 *
 * Description        : Setting the yp slice monitoring threshold
 * \endverbatim
 *******************************************************************************************************/
void Mcu_Ip_CkgenIpMonSetThrd(uint32 base, uint32 id,
                              uint16 lowThrd, uint16 highThrd)
{
    uint32 monThrd = base + IP_SLICE_MON_THRD_OFF(id);
    uint32 value;

    value = FV_IP_SLICE_MON_THRD_HIGH_THRD(highThrd) | FV_IP_SLICE_MON_THRD_LOW_THRD(lowThrd);
    writel(value, monThrd);
}
/** *****************************************************************************************************
 * \brief Setting the bus slice monitoring threshold
 *
 * \verbatim
 * Syntax             : void Mcu_Ip_CkgenBusMonSetThrd(uint32 base, uint32 type, uint32 id,
                               uint16 lowThrd, uint16 highThrd)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - CKGEN base address
 *                      type - bus slice type
 *                      id - slice id
 *                      lowThrd/highThrd - lowThrd, (unit:24M/(clk_24m_div_a/b +1)/2, freq_cnt should be in the range.)
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : None
 *
 * Description        : Setting the bus slice monitoring threshold
 * \endverbatim
 *******************************************************************************************************/
void Mcu_Ip_CkgenBusMonSetThrd(uint32 base, uint32 type, uint32 id,
                               uint16 lowThrd, uint16 highThrd)
{
    uint32 busMonThrd;
    uint32 value;

    if (CKGEN_BUS_ID_TYPE_DIV_N == type)
    {
        busMonThrd = base + BUS_SLICE_MON_1_THRD_OFF(id);
    }
    else if (CKGEN_BUS_ID_TYPE_DIV_P == type)
    {
        busMonThrd = base + BUS_SLICE_MON_2_THRD_OFF(id);
    }
    else if (CKGEN_BUS_ID_TYPE_DIV_Q == type)
    {
        busMonThrd = base + BUS_SLICE_MON_3_THRD_OFF(id);
    }
    else
    {
        busMonThrd = base + BUS_SLICE_MON_0_THRD_OFF(id);
    }

    value = FV_BUS_SLICE_MON_0_THRD_HIGH_THRD(highThrd) | FV_BUS_SLICE_MON_0_THRD_LOW_THRD(lowThrd);
    writel(value, busMonThrd);
}

/** *****************************************************************************************************
 * \brief Setting the dbgMon monitoring threshold
 *
 * \verbatim
 * Syntax             : void Mcu_Ip_CkgenDbgMonSetThrd(uint32 base, uint16 lowThrd, uint16 highThrd)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - CKGEN base address
 *                      lowThrd - lowThrd
 *                      highThrd - highThrd
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : None
 *
 * Description        : Setting the dbgMon monitoring threshold
 * \endverbatim
 *******************************************************************************************************/
void Mcu_Ip_CkgenDbgMonSetThrd(uint32 base, uint16 lowThrd, uint16 highThrd)
{
    uint32 monThrd = base + MON_CHK_THRD_OFF;
    uint32 value = FV_MON_CHK_THRD_HIGH(highThrd) | FV_MON_CHK_THRD_LOW(lowThrd);
    writel(value, monThrd);
}

/** *****************************************************************************************************
 * \brief Setting the 24M/32K monitoring threshold
 *
 * \verbatim
 * Syntax             : void Mcu_Ip_Ckgen24MMonSetThrd(uint32 base,
                                      uint16 lowThrd, uint16 highThrd)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - CKGEN base address
 *                      lowThrd - lowThrd
 *                      highThrd - highThrd
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : None
 *
 * Description        : Setting the 24M/32K monitoring threshold
 * \endverbatim
 *******************************************************************************************************/
void Mcu_Ip_Ckgen24MMonSetThrd(uint32 base, uint16 lowThrd, uint16 highThrd)
{
    uint32 monThrd = base + LOW_SPD_CHK_THRD_OFF;
    uint32 value = FV_LOW_SPD_CHK_THRD_HIGH(highThrd) | FV_LOW_SPD_CHK_THRD_LOW(lowThrd);
    writel(value, monThrd);
}

/** *****************************************************************************************************
 * \brief Get Monitor Moudel Freq interface
 *
 * \verbatim
 * Syntax             : uint32 Mcu_Ip_CkgenGetMonitorClock(uint32 base, Mcu_CkgenType sliceType, uint32 typeIndex,
                                                                    uint32 rate)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - CKGEN base address
 *                      sliceType - sliceType
 *                      typeIndex - slcie index
 *                      rate - Expected frequency
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : real rate
 *
 * Description        : get the monitoring rate
 *                      Using 24M/div/2 as the monitoring frequency,
 *                      the number of waveforms at the monitored frequency during this period is recorded in the registers
 *                      and used to calculate the monitored frequency.
 *                      if clock loss happened, the recorded value will be cleaned.
 *                      if expected frequency less than 1M, need switch divnum
 * \endverbatim
 *******************************************************************************************************/
uint32 Mcu_Ip_CkgenGetMonitorClock(uint32 base, Mcu_CkgenType sliceType, uint32 typeIndex,
                                   uint32 rate)
{
    uint32 ui32MonBaseClk = UINT32_MAX;
    uint32 ui32GlbCtrlVal;
    uint8 ui8IpMonSrcSel;
    uint16 ui16ClkMonDiv;

    if (sliceType <= CKGEN_FS32K_TYPE)
    {
        if (CKGEN_FS24M_TYPE == sliceType)
        {
            ui32MonBaseClk = LOW_32K_FREQ;
        }
        else
        {
            /* set mon div_num_a/b */
            Mcu_Ip_CkgenSetMonDivNum(base, CKGEN_MON_DIVA, 0x3FFU);
            Mcu_Ip_CkgenSetMonDivNum(base, CKGEN_MON_DIVB, 0x27FFU);

            /* select use clk_mon_a/b */
            ui8IpMonSrcSel = Mcu_Ip_CkgenSelectMonAorB(base, sliceType, typeIndex, rate);

            /* Ip Mon src selection mon-b*/
            if (1U == ui8IpMonSrcSel)
            {
                ui32GlbCtrlVal = readl(base + CKGEN_GLB_CTL1_OFF);

                ui16ClkMonDiv = (uint16)GFV_CKGEN_GLB_CTL1_CLK_24M_DIV_B_NUM(ui32GlbCtrlVal);
                ui32MonBaseClk = CKGEN_24M_RATE / ((uint32)ui16ClkMonDiv + 1U);
                ui32MonBaseClk = ui32MonBaseClk / 2U;
            }
            /* Ip Mon src selection mon-a*/
            else if (0U == ui8IpMonSrcSel)
            {
                ui32GlbCtrlVal = readl(base + CKGEN_GLB_CTL1_OFF);

                ui16ClkMonDiv = (uint16)GFV_CKGEN_GLB_CTL1_CLK_24M_DIV_A_NUM(ui32GlbCtrlVal);
                ui32MonBaseClk = CKGEN_24M_RATE / ((uint32)ui16ClkMonDiv + 1U);
                ui32MonBaseClk = ui32MonBaseClk / 2U;
            }
            else
            {
                ; /* do nothing */
            }
        }
    }

    return ui32MonBaseClk;

}

/** *****************************************************************************************************
 * \brief Get DbgMon Monitor Moudel Freq interface
 *
 * \verbatim
 * Syntax             : uint32 Mcu_Ip_CkgenGetDbgMonClock(uint32 base, uint32 rate)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - CKGEN base address
 *                      sliceType - sliceType
 *                      typeIndex - slcie index
 *                      rate - Expected frequency
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : real rate
 *
 * Description        : Get DbgMon Monitor Moudel Freq interface
 *                      Using 24M/div/2 as the monitoring frequency,
 *                      the number of waveforms at the monitored frequency during this period is recorded in the registers
 *                      and used to calculate the monitored frequency.
 *                      if clock loss happened, the recorded value will be cleaned.
 *                      if expected frequency less than 1M, need switch divnum
 * \endverbatim
 *******************************************************************************************************/
uint32 Mcu_Ip_CkgenGetDbgMonClock(uint32 base, uint32 rate)
{
    uint32 ui32MonBaseClk;
    uint32 ui32GlbCtrlVal;
    uint8 ui8IpMonSrcSel;
    uint16 ui16ClkMonDiv;

    /* set mon div_num_a/b */
    Mcu_Ip_CkgenSetMonDivNum(base, CKGEN_MON_DIVA, 0x3FFU);
    Mcu_Ip_CkgenSetMonDivNum(base, CKGEN_MON_DIVB, 0x27FFU);

    /* select use clk_mon_a/b */
    ui8IpMonSrcSel = Mcu_Ip_CkgenDbgMonSelectAorB(base, rate);

    /* dbgMon src selection mon-b*/
    if (1U == ui8IpMonSrcSel)
    {
        ui32GlbCtrlVal = readl(base + CKGEN_GLB_CTL1_OFF);

        ui16ClkMonDiv = (uint16)GFV_CKGEN_GLB_CTL1_CLK_24M_DIV_B_NUM(ui32GlbCtrlVal);
        ui32MonBaseClk = CKGEN_24M_RATE / ((uint32)ui16ClkMonDiv + 1U);
        ui32MonBaseClk = ui32MonBaseClk / 2U;
    }
    /* dbgMon src selection mon-a*/
    else
    {
        ui32GlbCtrlVal = readl(base + CKGEN_GLB_CTL1_OFF);

        ui16ClkMonDiv = (uint16)GFV_CKGEN_GLB_CTL1_CLK_24M_DIV_A_NUM(ui32GlbCtrlVal);
        ui32MonBaseClk = CKGEN_24M_RATE / ((uint32)ui16ClkMonDiv + 1U);
        ui32MonBaseClk = ui32MonBaseClk / 2U;
    }

    return ui32MonBaseClk;

}

/** *****************************************************************************************************
 * \brief get the ip slice monitoring rate
 *
 * \verbatim
 * Syntax             : Mcu_CkgenRateType Mcu_Ip_CkgenIpMonGetRate(uint32 base, uint32 id)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - CKGEN base address
 *                      id - slice id
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : ip slice monitoring rate
 *
 * Description        : get the ip slice monitoring rate
 *                      Using 24M/div/2 as the monitoring frequency, clk_24m_mona/clk_24m_monb are used for clock frequency monitor.
 *                      the number of waveforms at the monitored frequency during this period is recorded in the registers
 *                      and used to calculate the monitored frequency.
 *                      if clock loss happened, the recorded value will be cleaned.
 * \endverbatim
 *******************************************************************************************************/
Mcu_CkgenRateType Mcu_Ip_CkgenIpMonGetRate(uint32 base, uint32 id, Mcu_ClkRateType rate)
{
    uint32 ipMonCtrl = base + IP_SLICE_MON_CTL_OFF(id);
    uint32 ipCtrl = base + IP_SLICE_CTL_OFF(id);
    uint32 ipMonCtrlVal;
    uint32 waitTimeoutFlag;
    uint16 freqMon;
    uint8 divAorB;
    Mcu_ClkRateType rateGet = UINT32_MAX;
    Std_ReturnType errStatus = E_OK;
    uint32 value = (readl(ipMonCtrl) & BM_IP_SLICE_MON_CTL_MON_EN);

    /* disable ip mon */
    if (0U != value)
    {
        errStatus = Mcu_Ip_CkgenMonEnable(base, CKGEN_IP_SLICE_TYPE, id, 0U, FALSE);
    }/* else not needed */

    if (E_OK == errStatus)
    {
        /* clear freq mon */
        value = readl(ipMonCtrl);
        value &= ~BM_IP_SLICE_MON_CTL_FREQ_MON_UPD;
        value &= ~FM_IP_SLICE_MON_CTL_FREQ_MON;
        writel(value, ipMonCtrl);

        /* set mon div_num_a/b */
        Mcu_Ip_CkgenSetMonDivNum(base, CKGEN_MON_DIVA, 0x3FFU);
        Mcu_Ip_CkgenSetMonDivNum(base, CKGEN_MON_DIVB, 0x27FFU);

        /* select use clk_mon_a/b */
        divAorB = Mcu_Ip_CkgenSelectMonAorB(base, CKGEN_IP_SLICE_TYPE, id, rate);

        /* enable ip slice debug */
        value = readl(ipCtrl);
        value |= BM_IP_SLICE_CTL_DBG_EN;
        writel(value, ipCtrl);

        /* enable ip mon */
        errStatus = Mcu_Ip_CkgenMonEnable(base, CKGEN_IP_SLICE_TYPE, id, 0U, TRUE);

        if (E_OK == errStatus)
        {
            waitTimeoutFlag = Mcu_Ip_WaitForBitTimes(ipMonCtrl, BM_IP_SLICE_MON_CTL_FREQ_MON_UPD, 1U, CKGEN_WAIT_TIME);
            McuFaultInj_Mcu_Ip_Mcu_Ip_CkgenIpMonGetRate_01();
            if (TRUE == waitTimeoutFlag)
            {
                ipMonCtrlVal = readl(ipMonCtrl);

                freqMon = (uint16)GFV_IP_SLICE_MON_CTL_FREQ_MON(ipMonCtrlVal);

                rateGet = Mcu_Ip_CkgenMonCalcFreq(base, freqMon, divAorB);
            } /* else not needed */
        } /* else not needed */

    }

    return rateGet;
}

/** *****************************************************************************************************
 * \brief get the bus slice monitoring rate
 *
 * \verbatim
 * Syntax             : Mcu_CkgenRateType Mcu_Ip_CkgenBusMonGetRate(uint32 base, uint32 id, uint32 type)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - CKGEN base address
 *                      id - slice id
 *                      type - MNPQ type
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : bus slice monitoring rate
 *
 * Description        : get the bus slice monitoring rate
 *                      Using 24M/div/2 as the monitoring frequency, clk_24m_mona/clk_24m_monb are used for clock frequency monitor.
 *                      the number of waveforms at the monitored frequency during this period is recorded in the registers
 *                      and used to calculate the monitored frequency.
 *                      if clock loss happened, the recorded value will be cleaned.
 * \endverbatim
 *******************************************************************************************************/
Mcu_CkgenRateType Mcu_Ip_CkgenBusMonGetRate(uint32 base, uint32 id, uint32 type, uint32 rate)
{
    uint32 busMonCtrl = base + BUS_SLICE_MON_CTL_0_OFF(id);
    uint32 busMonOut;
    uint32 busCtrl = base + BUS_SLICE_CTL_OFF(id);
    uint32 freqMonUpdBM;
    uint32 waitTimeoutFlag;
    uint16 freqMon;
    uint8 divAorB;
    Mcu_CkgenRateType rateGet = UINT32_MAX;
    Std_ReturnType errStatus = E_OK;
    uint32 value = (readl(busMonCtrl) & BM_BUS_SLICE_MON_CTL_0_MON_EN);

    freqMonUpdBM = Mcu_Ip_CkgenBusMonType(base, id, type, &busMonOut);

    /* disable bus mon */
    if (0U != value)
    {
        errStatus = Mcu_Ip_CkgenMonEnable(base, CKGEN_SF_BUS_SLICE_TYPE, id, 0U, FALSE);
    } /* else not needed */

    if (E_OK == errStatus)
    {
        /* clear freq mon */
        writel(0U, busMonOut);

        value = readl(busMonCtrl);
        value &= ~freqMonUpdBM;
        writel(value, busMonCtrl);

        /* set mon div_num_a/b */
        Mcu_Ip_CkgenSetMonDivNum(base, CKGEN_MON_DIVA, 0x3FFU);
        Mcu_Ip_CkgenSetMonDivNum(base, CKGEN_MON_DIVB, 0x27FFU);

        /* select use clk_mon_a/b */
        divAorB = Mcu_Ip_CkgenSelectMonAorB(base, CKGEN_SF_BUS_SLICE_TYPE, id, rate);

        /* enable bus slice debug */
        value = readl(busCtrl);
        value |= BM_BUS_SLICE_CTL_DBG_EN;
        writel(value, busCtrl);

        /* enable bus mon */
        errStatus = Mcu_Ip_CkgenMonEnable(base, CKGEN_SF_BUS_SLICE_TYPE, id, 0U, TRUE);

        if (E_OK == errStatus)
        {
            waitTimeoutFlag = Mcu_Ip_WaitForBitTimes(busMonCtrl, freqMonUpdBM, 1U, CKGEN_WAIT_TIME);
            McuFaultInj_Mcu_Ip_CkgenBusMonGetRate_01();
            if (TRUE == waitTimeoutFlag)
            {
                /* recorded frequency number*/
                if (CKGEN_BUS_ID_TYPE_DIV_N == type)
                {
                    freqMon = (uint16)GFV_BUS_SLICE_MON_CTL_1_FREQ_MON_1(readl(busMonOut));
                }
                else if (CKGEN_BUS_ID_TYPE_DIV_P == type)
                {
                    freqMon = (uint16)GFV_BUS_SLICE_MON_CTL_2_FREQ_MON_2(readl(busMonOut));
                }
                else if (CKGEN_BUS_ID_TYPE_DIV_Q == type)
                {
                    freqMon = (uint16)GFV_BUS_SLICE_MON_CTL_2_FREQ_MON_3(readl(busMonOut));
                }
                else
                {
                    freqMon = (uint16)GFV_BUS_SLICE_MON_CTL_1_FREQ_MON_0(readl(busMonOut));
                }
                rateGet = Mcu_Ip_CkgenMonCalcFreq(base, freqMon, divAorB);
            } /* else not needed */
        } /* else not needed */


    }

    return rateGet;
}

/** *****************************************************************************************************
 * \brief get the 24M/32K monitoring rate
 *
 * \verbatim
 * Syntax             : uint32 Mcu_Ip_Ckgen24MMonGetRate(uint32 base)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - CKGEN base address
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : ip slice monitoring rate
 *
 * Description        : get the 24M/32K monitoring rate
 *                      Using 24M/32K as monitoring frequency for each other,
 *                      the number of waveforms at the monitored frequency during this period is recorded in the registers
 *                      and used to calculate the monitored frequency.
 *                      if clock loss happened, the recorded value will be cleaned.
 * \endverbatim
 *******************************************************************************************************/
uint32 Mcu_Ip_Ckgen24MMonGetRate(uint32 base)
{
    uint32 lowSpdChkCtl = base + LOW_SPD_CHK_CTL_OFF;
    uint32 monVal;
    uint32 freqMon;
    uint32 waitTimeoutFlag;
    uint32 rate = UINT32_MAX;
    Std_ReturnType errStatus = E_OK;
    uint32 value = (readl(lowSpdChkCtl) & BM_LOW_SPD_CHK_CTL_MON_EN_STA);

    McuFaultInj_Mcu_Ip_Ckgen24MMonGetRate_01();

    if (0U != value)
    {
        errStatus = Mcu_Ip_CkgenMonEnable(base, CKGEN_FS24M_TYPE, 0U, 0U, FALSE);
    }/* else not needed */

    McuFaultInj_Mcu_Ip_Ckgen24MMonGetRate_02();

    if (E_OK == errStatus)
    {
        /* set 32k 24m src */
        value = readl(lowSpdChkCtl);
        value &= ~FM_LOW_SPD_CHK_CTL_32K_SRC_SEL;
        value &= ~FM_LOW_SPD_CHK_CTL_24M_SRC_SEL;

        /* clear freq mon */
        value &= ~BM_LOW_SPD_CHK_CTL_FREQ_MON_UPD;
        value &= ~FM_LOW_SPD_CHK_CTL_FREQ_MON;

        /* enable mon */
        value &= ~BM_LOW_SPD_CHK_CTL_CLK_LOSS_DIS;
        writel(value, lowSpdChkCtl);

        errStatus = Mcu_Ip_CkgenMonEnable(base, CKGEN_FS24M_TYPE, 0U, 0U, TRUE);

        if (E_OK == errStatus)
        {
            waitTimeoutFlag = Mcu_Ip_WaitForBitTimes(lowSpdChkCtl, BM_LOW_SPD_CHK_CTL_FREQ_MON_UPD, 1U,
                CKGEN_WAIT_TIME);
            McuFaultInj_Mcu_Ip_Ckgen24MMonGetRate_03();
            if (TRUE == waitTimeoutFlag)
            {
                monVal = readl(lowSpdChkCtl);
                freqMon = GFV_LOW_SPD_CHK_CTL_FREQ_MON(monVal);
                rate = freqMon * LOW_32K_FREQ;
            } /* else not needed */

            (void)Mcu_Ip_CkgenMonEnable(base, CKGEN_FS24M_TYPE, 0U, 0U, FALSE);
        } /* else not needed */
    }

    return rate;
}
/** *****************************************************************************************************
 * \brief get the dbgMon monitoring rate
 *
 * \verbatim
 * Syntax             : Mcu_CkgenRateType Mcu_Ip_CkgenDbgMonGetRate(uint32 base, uint32 type, uint32 id, Mcu_ClkRateType rate)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - CKGEN base address
 *                      type - slice type
 *                      id - slice index
 *                      rate - expect rate
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : ip slice monitoring rate
 *
 * Description        : get the dbgMon monitoring rate
 *                      Using 24M/div/2 as the monitoring frequency, clk_24m_mona/clk_24m_monb are used for clock frequency monitor.
 *                      the number of waveforms at the monitored frequency during this period is recorded in the registers
 *                      and used to calculate the monitored frequency.
 *                      if clock loss happened, the recorded value will be cleaned.
 * \endverbatim
 *******************************************************************************************************/
Mcu_CkgenRateType Mcu_Ip_CkgenDbgMonGetRate(uint32 base, uint32 type, uint32 id,
        Mcu_ClkRateType rate)
{
    uint32 DbgMonCtrl = base + MON_CTL_OFF;
    uint32 DbgMonCtrlVal;
    uint32 sliceCtrl;
    uint32 waitTimeoutFlag;
    uint16 freqMon;
    uint8 divAorB;
    Mcu_ClkRateType rateGet = UINT32_MAX;
    Std_ReturnType errStatus = E_OK;
    uint32 value = (readl(DbgMonCtrl) & BM_MON_CTL_MON_EN);

    /* disable dbg mon */
    if (0U != value)
    {
        errStatus = Mcu_Ip_CkgenDbgMonEnable(base, FALSE);
    }/* else not needed */

    if (E_OK == errStatus)
    {
        /* clear freq mon */
        value = readl(DbgMonCtrl);

        value &= ~FM_MON_CTL_FREQ_MON;
        value &= ~BM_MON_CTL_FREQ_MON_UPD;
        writel(value, DbgMonCtrl);

        /* set mon div_num_a/b */
        Mcu_Ip_CkgenSetMonDivNum(base, CKGEN_MON_DIVA, 0x3FFU);
        Mcu_Ip_CkgenSetMonDivNum(base, CKGEN_MON_DIVB, 0x27FFU);

        /* select use clk_mon_a/b */
        divAorB = Mcu_Ip_CkgenDbgMonSelectAorB(base, rate);

        /* enable slice debug */
        if (0U == type)
        {
            sliceCtrl = base + IP_SLICE_CTL_OFF(id);
            value = readl(sliceCtrl);
            value |= BM_IP_SLICE_CTL_DBG_EN;
            writel(value, sliceCtrl);
        }
        else if (1U == type)
        {
            sliceCtrl = base + BUS_SLICE_CTL_OFF(id);
            value = readl(sliceCtrl);
            value |= BM_BUS_SLICE_CTL_DBG_EN;
            writel(value, sliceCtrl);
        }
        else if (3U == type)
        {
            if (APB_CKGEN_SAFETY_BASE == base)
            {
                if ((6U == id) || (7U == id))
                {
                    value = readl(base + BCG_CTL_OFF(0U));
                    value |= BM_BCG_CTL_DBG_EN;
                    writel(value, (base + BCG_CTL_OFF(0U)));
                }
                else if((8U == id) || (9U == id))
                {
                    value = readl(base + BCG_CTL_OFF(5U));
                    value |= BM_BCG_CTL_DBG_EN;
                    writel(value, (base + BCG_CTL_OFF(5U)));
                }
                else
                {
                    ; /*do nothing */
                }
            }
            else
            {
                if ((0U == id) || (1U == id))
                {
                    value = readl(base + BCG_CTL_OFF(0U));
                    value |= BM_BCG_CTL_DBG_EN;
                    writel(value, (base + BCG_CTL_OFF(0U)));
                }
                else if ((2U == id) || (3U == id))
                {
                    value = readl(base + PCG_CTL_OFF(71U));
                    value |= BM_PCG_CTL_DBG_EN;
                    writel(value, (base + PCG_CTL_OFF(71U)));

                    value = readl(base + PCG_CTL_OFF(72U));
                    value |= BM_PCG_CTL_DBG_EN;
                    writel(value, (base + PCG_CTL_OFF(72U)));
                }
                else
                {
                    ; /*do nothing */
                }
            }
        }
        else
        {
            ;/* do nothing */
        }

        /* enable dbg mon */
        errStatus = Mcu_Ip_CkgenDbgMonEnable(base, TRUE);

        if (E_OK == errStatus)
        {
            waitTimeoutFlag = Mcu_Ip_WaitForBitTimes(DbgMonCtrl, BM_MON_CTL_FREQ_MON_UPD, 1U, CKGEN_WAIT_TIME);
            McuFaultInj_Mcu_Ip_CkgenDbgMonGetRate_01();
            if (TRUE == waitTimeoutFlag)
            {
                DbgMonCtrlVal = readl(DbgMonCtrl);

                freqMon = (uint16)GFV_MON_CTL_FREQ_MON(DbgMonCtrlVal);

                rateGet = Mcu_Ip_CkgenMonCalcFreq(base, freqMon, divAorB);
            } /* else not needed */
        } /* else not needed */

    }

    return rateGet;
}

/** *****************************************************************************************************
 * \brief This function used for enable/disable slice frequency monitor.
 *
 * \verbatim
 * Syntax             : Std_ReturnType Mcu_Ip_CkgenMonEnable(uint32 base, Mcu_CkgenType type, uint32 id, boolean enable)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - ckgen base
 *                      type - slice type
 *                      id - slice index
 *                      timeout - wdt timeout
 *                      enable - TRUE: enable, FALSE: disable
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : None
 *
 * Description        : This function used for enable/disable slice frequency monitor.
 * \endverbatim
 *******************************************************************************************************/
Std_ReturnType Mcu_Ip_CkgenMonEnable(uint32 base, Mcu_CkgenType type, uint32 id, uint32 timeout,
                                     boolean enable)
{
    Std_ReturnType errStatus = E_OK;
    uint32 monCtrl;
    uint32 value;

    switch (type)
    {
    case CKGEN_IP_SLICE_TYPE:
        monCtrl = base + IP_SLICE_MON_CTL_OFF(id);
        value = readl(monCtrl);
        value &= ~BM_IP_SLICE_MON_CTL_MON_EN;
        value |= enable;
        writel(value, monCtrl);

        if (FALSE == Mcu_Ip_WaitForBitTimes(monCtrl, BM_IP_SLICE_MON_CTL_MON_EN_STA, enable, CKGEN_WAIT_TIME))
        {
            errStatus = MCU_E_TIMEOUT;
        }
        else
        {
            /* set cor/unc enable/disable */
            monCtrl = base + IP_CLK_COR_EN_OFF(id / 32U);
            value = readl(monCtrl);
            value &= ~(1UL << (id % 32U));
            value |= ((uint32)enable << (id % 32U));
            writel(value, monCtrl);

            monCtrl = base + IP_CLK_UNC_EN_OFF(id / 32U);
            value = readl(monCtrl);
            value &= ~(1UL << (id % 32U));
            value |= ((uint32)enable << (id % 32U));
            writel(value, monCtrl);
        }
        break;

    case CKGEN_SF_BUS_SLICE_TYPE:
    case CKGEN_BUS_SLICE_TYPE:
        monCtrl = base + BUS_SLICE_MON_CTL_0_OFF(id);
        value = readl(monCtrl);
        value &= ~BM_BUS_SLICE_MON_CTL_0_MON_EN;
        value |= enable;
        writel(value, monCtrl);

        if (FALSE == Mcu_Ip_WaitForBitTimes(monCtrl, BM_BUS_SLICE_MON_CTL_0_MON_EN_STA,
                                            enable, CKGEN_WAIT_TIME))
        {
            errStatus = MCU_E_TIMEOUT;
        }
        else
        {
            /* set cor/unc enable/disable */
            monCtrl = base + BUS_CLK_COR_EN_OFF;
            value = readl(monCtrl);
            value &= ~(1UL << (id % 32U));
            value |= ((uint32)enable << (id % 32U));
            writel(value, monCtrl);

            monCtrl = base + BUS_CLK_UNC_EN_OFF;
            value = readl(monCtrl);
            value &= ~(1UL << (id % 32U));
            value |= ((uint32)enable << (id % 32U));
            writel(value, monCtrl);
        }
        break;

    case CKGEN_FS24M_TYPE:
        monCtrl = base + LOW_SPD_CHK_CTL_OFF;
        value = readl(monCtrl);
        value &= ~BM_LOW_SPD_CHK_CTL_MON_EN;
        value |= ((uint32)enable << 1U);
        writel(value, monCtrl);

        if (FALSE == Mcu_Ip_WaitForBitTimes(monCtrl, BM_LOW_SPD_CHK_CTL_MON_EN_STA,
                                            enable, CKGEN_WAIT_TIME))
        {
            errStatus = MCU_E_TIMEOUT;
        } /* else not needed */

        /* set cor/unc enable/disable */
        monCtrl = base + LOW_SPD_COR_EN_OFF;
        value = readl(monCtrl);
        value &= ~BM_LOW_SPD_COR_EN_INT_EN;
        value |= enable;
        writel(value, monCtrl);

        monCtrl = base + LOW_SPD_UNC_EN_OFF;
        value = readl(monCtrl);
        value &= ~BM_LOW_SPD_UNC_EN_INT_EN;
        value |= enable;
        writel(value, monCtrl);
        break;

    case CKGEN_PCG_TYPE:
        Mcu_Ip_CkgenXcgAmonEnable(base, id, CKGEN_CG_ID_TYPE_PCG_TYPE, enable);
        break;

    case CKGEN_BCG_TYPE:
        Mcu_Ip_CkgenXcgAmonEnable(base, id, CKGEN_CG_ID_TYPE_BCG_TYPE, enable);
        break;

    case CKGEN_PLL_CG_TYPE:
        errStatus = Mcu_Ip_CkgenPllMonEnable(base, id, timeout, enable);
        break;

    case CKGEN_XTAL_CG_TYPE:
        errStatus = Mcu_Ip_CkgenXtalMonEnable(base, timeout, enable);
        break;

    default:
        errStatus = MCU_E_PARAM_CONFIG;
        break;
    }

    return errStatus;
}

/** *****************************************************************************************************
 * \brief This function used for enable/disable dbgMon frequency monitor.
 *
 * \verbatim
 * Syntax             : Std_ReturnType Mcu_Ip_CkgenDbgMonEnable(uint32 base, boolean enable)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - ckgen base
 *                      enable - TRUE: enable, FALSE: disable
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : None
 *
 * Description        : This function used for enable/disable dbgMon frequency monitor.
 * \endverbatim
 *******************************************************************************************************/
Std_ReturnType Mcu_Ip_CkgenDbgMonEnable(uint32 base, boolean enable)
{
    Std_ReturnType errStatus = E_OK;
    uint32 monCtrl = base + MON_CTL_OFF;
    uint32 value = readl(monCtrl);

    value &= ~BM_MON_CTL_MON_EN;
    value |= enable;
    writel(value, monCtrl);

    if (FALSE == Mcu_Ip_WaitForBitTimes(monCtrl, BM_MON_CTL_MON_EN_STA,
                                        enable, CKGEN_WAIT_TIME))
    {
        errStatus = MCU_E_TIMEOUT;
    } /* else not needed */

    /* set cor/unc enable/disable */
    monCtrl = base + MON_COR_EN_OFF;
    value = readl(monCtrl);
    value &= ~BM_MON_COR_EN_INT_EN;
    value |= enable;
    writel(value, monCtrl);

    monCtrl = base + MON_UNC_EN_OFF;
    value = readl(monCtrl);
    value &= ~BM_MON_UNC_EN_INT_EN;
    value |= enable;
    writel(value, monCtrl);

    return errStatus;
}
/** *****************************************************************************************************
 * \brief config duty and jitter, enable/disable cqm monitor.
 *
 * \verbatim
 * Syntax             : void Mcu_Ip_CkgenCqmEnable(uint32 base, uint16 duty, uint16 jitter, boolean enable)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - CKGEN base address
 *                      duty - duty
 *                      jitter - jitter
 *                      enable - TRUE/FALSE
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : None
 *
 * Description        : config duty and jitter, enable/disable cqm monitor.
 *
 * \endverbatim
 *******************************************************************************************************/
void Mcu_Ip_CkgenCqmEnable(uint32 base, uint32 cqmIndex, uint16 duty, uint16 jitter, boolean enable)
{
    uint32 dbgMonCtl = base + DBG_MON_CTL_OFF;
    uint32 cqmCtl = base + CQM_CTL_OFF(cqmIndex);
    uint32 value = readl(dbgMonCtl);

    /* enable/disable cqm gating */
    value |= BM_DBG_MON_CTL_CQM_GATING_EN;
    writel(value, dbgMonCtl);

    if (TRUE == enable)
    {
        /* config cqm jitter and duty */
        value = readl(cqmCtl);
        value &= ~FM_CQM_CTL_DUTY_RATE;
        value |= FV_CQM_CTL_DUTY_RATE(duty);

        value &= ~FM_CQM_CTL_JITTER_RATE;
        value |= FV_CQM_CTL_JITTER_RATE(jitter);
        writel(value, cqmCtl);
    }

    /* enable/disable cqm mon */
    value = readl(cqmCtl);
    value &= ~BM_CQM_CTL_MON_EN;
    value |= enable;
    writel(value, cqmCtl);

    /* set cor/unc enable/disable */
    cqmCtl = base + CQM_COR_EN_OFF;
    value = readl(cqmCtl);
    value &= ~(1UL << cqmIndex);
    value |= ((uint32)enable << cqmIndex);
    writel(value, cqmCtl);

    cqmCtl = base + MON_UNC_EN_OFF;
    value = readl(cqmCtl);
    value &= ~(1UL << cqmIndex);
    value |= ((uint32)enable << cqmIndex);
    writel(value, cqmCtl);
}

#define MCU_STOP_SEC_CODE
#include "Mcu_MemMap.h"
/* End of file */
